import React, { useState, useRef } from 'react';
import {
  Box,
  Typography,
  Alert,
  LinearProgress,
  TextField,
  MenuItem,
} from '@mui/material';
import SmartDisplayIcon from '@mui/icons-material/SmartDisplay';
import { useStoryWriterState } from '../../../hooks/useStoryWriterState';
import { storyWriterApi } from '../../../services/storyWriterApi';
import { triggerSubscriptionError } from '../../../api/client';
import { OperationButton } from '../../shared/OperationButton';
import SceneVideoApproval from './SceneVideoApproval';

// Simple logger for frontend
const logger = {
  error: (message: string, ...args: any[]) => console.error(`[HdVideoSection] ${message}`, ...args),
  warn: (message: string, ...args: any[]) => console.warn(`[HdVideoSection] ${message}`, ...args),
  info: (message: string, ...args: any[]) => console.info(`[HdVideoSection] ${message}`, ...args),
};

const VIDEO_MODEL_OPTIONS = [
  {
    id: 'huggingface:tencent/HunyuanVideo',
    provider: 'huggingface',
    model: 'tencent/HunyuanVideo',
    label: 'HuggingFace · HunyuanVideo',
  },
  {
    id: 'wavespeed:hunyuan-video-1.5',
    provider: 'wavespeed',
    model: 'hunyuan-video-1.5',
    label: 'WaveSpeed · HunyuanVideo-1.5',
  },
];

const getDefaultVideoOptionId = (storyMode: 'marketing' | 'pure') =>
  storyMode === 'marketing' ? 'huggingface:tencent/HunyuanVideo' : 'wavespeed:hunyuan-video-1.5';

interface HdVideoSectionProps {
  state: ReturnType<typeof useStoryWriterState>;
  error: string | null;
  onError: (error: string | null) => void;
}

export const HdVideoSection: React.FC<HdVideoSectionProps> = ({ state, onError }) => {
  const [isGeneratingHdVideo, setIsGeneratingHdVideo] = useState(false);
  const [hdVideoProgress, setHdVideoProgress] = useState(0);
  const [hdVideoMessage, setHdVideoMessage] = useState<string>('');
  const [hdVideoPrompts, setHdVideoPrompts] = useState<Map<number, string>>(new Map());
  const [selectedVideoOptionId, setSelectedVideoOptionId] = useState<string>(
    getDefaultVideoOptionId(state.storyMode),
  );
  
  const [approvalModal, setApprovalModal] = useState<{
    open: boolean;
    sceneNumber: number;
    sceneTitle: string;
    videoUrl: string;
    promptUsed: string;
  } | null>(null);
  const [regeneratingScene, setRegeneratingScene] = useState<number | null>(null);
  
  const processSceneRef = useRef<((sceneIndex: number) => Promise<void>) | null>(null);

  const selectedVideoOption =
    VIDEO_MODEL_OPTIONS.find((option) => option.id === selectedVideoOptionId) ||
    VIDEO_MODEL_OPTIONS[0];

  const handleGenerateHdVideo = async () => {
    if (!state.outlineScenes || state.outlineScenes.length === 0) {
      onError('Please generate a structured outline first');
      return;
    }

    const scenes = state.outlineScenes;
    const totalScenes = scenes.length;
    
    if (!state.sceneHdVideos) {
      state.setSceneHdVideos(new Map());
    }
    
    setHdVideoPrompts(new Map());
    state.setHdVideoGenerationStatus('generating');
    setIsGeneratingHdVideo(true);
    onError(null);

    const storyContext = {
      persona: state.persona,
      story_setting: state.storySetting,
      characters: state.characters,
      plot_elements: state.plotElements,
      writing_style: state.writingStyle,
      story_tone: state.storyTone,
      narrative_pov: state.narrativePOV,
      audience_age_group: state.audienceAgeGroup,
      content_rating: state.contentRating,
      premise: state.premise || '',
      outline: state.outline || '',
      story_content: state.storyContent || '',
    };

    const processScene = async (sceneIndex: number): Promise<void> => {
      if (sceneIndex >= totalScenes) {
        state.setHdVideoGenerationStatus('completed');
        setIsGeneratingHdVideo(false);
        setHdVideoProgress(100);
        const approvedCount = state.sceneHdVideos?.size || 0;
        setHdVideoMessage(`HD video generation complete! ${approvedCount} of ${totalScenes} scenes approved.`);
        return;
      }

      const scene = scenes[sceneIndex];
      const sceneNumber = scene.scene_number || sceneIndex + 1;
      state.setCurrentHdSceneIndex(sceneIndex);
      
      setHdVideoProgress(Math.round((sceneIndex / totalScenes) * 100));
      setHdVideoMessage(`Generating HD video for Scene ${sceneNumber}...`);

      try {
        const result = await storyWriterApi.generateHdVideoScene({
          scene_number: sceneNumber,
          scene_data: scene,
          story_context: storyContext,
          all_scenes: scenes,
          provider: selectedVideoOption.provider,
          model: selectedVideoOption.model,
          num_frames: 50,
          guidance_scale: 7.5,
        });

        setHdVideoPrompts((prev) => {
          const newPrompts = new Map(prev);
          newPrompts.set(sceneNumber, result.prompt_used);
          return newPrompts;
        });

        state.setHdVideoGenerationStatus('awaiting_approval');
        setApprovalModal({
          open: true,
          sceneNumber: sceneNumber,
          sceneTitle: scene.title || `Scene ${sceneNumber}`,
          videoUrl: result.video_url,
          promptUsed: result.prompt_used,
        });

      } catch (err: any) {
        // Check if this is a subscription error (429/402) and trigger global subscription modal
        const status = err?.response?.status;
        if (status === 429 || status === 402) {
          const handled = await triggerSubscriptionError(err);
          if (handled) {
            // Subscription modal is showing, stop processing scenes
            setIsGeneratingHdVideo(false);
            state.setHdVideoGenerationStatus('idle');
            return;
          }
        }
        
        // Extract error message as string (handle both string and object responses)
        let errorMessage: string;
        if (err.response?.data?.detail) {
          const detail = err.response.data.detail;
          if (typeof detail === 'string') {
            errorMessage = detail;
          } else if (typeof detail === 'object' && detail !== null) {
            // Handle object response like {error: "...", message: "..."}
            errorMessage = detail.message || detail.error || JSON.stringify(detail);
          } else {
            errorMessage = String(detail);
          }
        } else {
          errorMessage = err.message || `Failed to generate HD video for scene ${sceneNumber}`;
        }
        onError(errorMessage);
        
        // CRITICAL: Stop processing on ANY error to prevent wasting money on expensive video API calls
        // This is an expensive operation ($0.40/video) - don't continue if there's an error
        // Only retry/continue if the user explicitly requests it
        logger.error(`[HdVideoSection] Video generation failed for scene ${sceneNumber}: ${errorMessage}`);
        logger.error(`[HdVideoSection] Stopping video generation to prevent wasted API calls`);
        
        setIsGeneratingHdVideo(false);
        state.setHdVideoGenerationStatus('idle');
        
        // Don't continue to next scene - stop immediately to save money
        return;
      }
    };

    processSceneRef.current = processScene;
    await processScene(0);
  };

  const handleApprove = () => {
    if (!approvalModal) return;
    
    const sceneNumber = approvalModal.sceneNumber;
    const hdVideos = state.sceneHdVideos || new Map();
    hdVideos.set(sceneNumber, approvalModal.videoUrl);
    state.setSceneHdVideos(new Map(hdVideos));
    
    setApprovalModal(null);
    
    const currentIndex = state.currentHdSceneIndex;
    const scenes = state.outlineScenes || [];
    if (currentIndex + 1 < scenes.length && processSceneRef.current) {
      state.setHdVideoGenerationStatus('generating');
      processSceneRef.current(currentIndex + 1);
    } else {
      state.setHdVideoGenerationStatus('completed');
      setIsGeneratingHdVideo(false);
      const approvedCount = state.sceneHdVideos?.size || 0;
      setHdVideoMessage(`HD video generation complete! ${approvedCount} of ${scenes.length} scenes approved.`);
    }
  };

  const handleReject = () => {
    if (!approvalModal) return;
    
    setApprovalModal(null);
    
    const currentIndex = state.currentHdSceneIndex;
    const scenes = state.outlineScenes || [];
    if (currentIndex + 1 < scenes.length && processSceneRef.current) {
      state.setHdVideoGenerationStatus('generating');
      processSceneRef.current(currentIndex + 1);
    } else {
      state.setHdVideoGenerationStatus('completed');
      setIsGeneratingHdVideo(false);
      const approvedCount = state.sceneHdVideos?.size || 0;
      setHdVideoMessage(`HD video generation complete! ${approvedCount} of ${scenes.length} scenes approved.`);
    }
  };

  const handleRegenerate = async () => {
    if (!approvalModal) return;
    
    const sceneNumber = approvalModal.sceneNumber;
    const scenes = state.outlineScenes || [];
    const sceneIndex = scenes.findIndex((s: any) => (s.scene_number || 0) === sceneNumber);
    const scene = scenes[sceneIndex];
    
    if (!scene) return;
    
    setRegeneratingScene(sceneNumber);
    
    try {
      const storyContext = {
        persona: state.persona,
        story_setting: state.storySetting,
        characters: state.characters,
        plot_elements: state.plotElements,
        writing_style: state.writingStyle,
        story_tone: state.storyTone,
        narrative_pov: state.narrativePOV,
        audience_age_group: state.audienceAgeGroup,
        content_rating: state.contentRating,
        premise: state.premise || '',
        outline: state.outline || '',
        story_content: state.storyContent || '',
      };

      const result = await storyWriterApi.generateHdVideoScene({
        scene_number: sceneNumber,
        scene_data: scene,
        story_context: storyContext,
        all_scenes: scenes,
        provider: selectedVideoOption.provider,
        model: selectedVideoOption.model,
        num_frames: 50,
        guidance_scale: 7.5,
      });

      setHdVideoPrompts((prev) => {
        const newPrompts = new Map(prev);
        newPrompts.set(sceneNumber, result.prompt_used);
        return newPrompts;
      });

      setApprovalModal({
        open: true,
        sceneNumber: sceneNumber,
        sceneTitle: scene.title || `Scene ${sceneNumber}`,
        videoUrl: result.video_url,
        promptUsed: result.prompt_used,
      });
    } catch (err: any) {
      // Check if this is a subscription error (429/402) and trigger global subscription modal
      const status = err?.response?.status;
      if (status === 429 || status === 402) {
        const handled = await triggerSubscriptionError(err);
        if (handled) {
          // Subscription modal is showing, stop here
          setRegeneratingScene(null);
          return;
        }
      }
      
      // Extract error message as string (handle both string and object responses)
      let errorMessage: string;
      if (err.response?.data?.detail) {
        const detail = err.response.data.detail;
        if (typeof detail === 'string') {
          errorMessage = detail;
        } else if (typeof detail === 'object' && detail !== null) {
          // Handle object response like {error: "...", message: "..."}
          errorMessage = detail.message || detail.error || JSON.stringify(detail);
        } else {
          errorMessage = String(detail);
        }
      } else {
        errorMessage = err.message || 'Failed to regenerate video';
      }
      onError(errorMessage);
    } finally {
      setRegeneratingScene(null);
    }
  };

  return (
    <>
      <Box sx={{ mt: 1, display: 'flex', flexDirection: 'column', gap: 1 }}>
        <TextField
          select
          label="HD Video Model"
          value={selectedVideoOptionId}
          onChange={(e) => setSelectedVideoOptionId(e.target.value)}
          size="small"
          sx={{ maxWidth: 320 }}
          disabled={
            isGeneratingHdVideo ||
            state.hdVideoGenerationStatus === 'awaiting_approval' ||
            state.hdVideoGenerationStatus === 'generating'
          }
        >
          {VIDEO_MODEL_OPTIONS.map((option) => (
            <MenuItem key={option.id} value={option.id}>
              {option.label}
            </MenuItem>
          ))}
        </TextField>
        <OperationButton
          operation={{
            provider: 'video',
            model: selectedVideoOption.model,
            tokens_requested: 0,
            operation_type: 'video_generation',
            actual_provider_name: selectedVideoOption.provider,
          }}
          label="Generate HD Animation with AI"
          variant="contained"
          startIcon={<SmartDisplayIcon />}
          showCost={true}
          checkOnHover={true}
          checkOnMount={false}
          onClick={handleGenerateHdVideo}
          disabled={isGeneratingHdVideo || state.hdVideoGenerationStatus === 'awaiting_approval'}
          loading={isGeneratingHdVideo || state.hdVideoGenerationStatus === 'awaiting_approval'}
          tooltipPlacement="top"
          buttonProps={{
            children: isGeneratingHdVideo || state.hdVideoGenerationStatus === 'awaiting_approval'
              ? 'Generating HD Animation...'
              : undefined,
          }}
        />
        
        {(isGeneratingHdVideo || state.hdVideoGenerationStatus === 'generating' || state.hdVideoGenerationStatus === 'awaiting_approval') && (
          <Box sx={{ mt: 2, p: 2, backgroundColor: '#FAF9F6', borderRadius: 1, border: '1px solid #E0DCD4' }}>
            <LinearProgress variant="determinate" value={hdVideoProgress} sx={{ mb: 1 }} />
            <Typography variant="body2" sx={{ color: '#5D4037', fontWeight: 500, mb: 1 }}>
              {hdVideoMessage || 'Generating HD video...'} {hdVideoProgress}%
            </Typography>
            {state.hdVideoGenerationStatus === 'awaiting_approval' && (
              <Typography variant="body2" sx={{ color: '#1976d2', display: 'block', mb: 1, fontWeight: 500 }}>
                ⏸ Awaiting your approval for Scene {state.currentHdSceneIndex + 1} of {state.outlineScenes?.length || 0}
              </Typography>
            )}
            {state.hdVideoGenerationStatus === 'generating' && (
              <Typography variant="body2" sx={{ color: '#5D4037', display: 'block', mb: 1 }}>
                Processing Scene {state.currentHdSceneIndex + 1} of {state.outlineScenes?.length || 0}...
              </Typography>
            )}
            {state.sceneHdVideos && state.sceneHdVideos.size > 0 && (
              <Typography variant="caption" sx={{ color: '#4caf50', display: 'block', mb: 1, fontWeight: 500 }}>
                ✓ {state.sceneHdVideos.size} of {state.outlineScenes?.length || 0} scenes approved
              </Typography>
            )}
            
            {hdVideoPrompts.size > 0 && (
              <Box sx={{ mt: 2 }}>
                <Typography variant="subtitle2" sx={{ color: '#1A1611', mb: 1, fontWeight: 600 }}>
                  Generated Prompts:
                </Typography>
                {Array.from(hdVideoPrompts.entries())
                  .sort(([a], [b]) => a - b)
                  .map(([sceneNum, prompt]) => (
                    <Box key={sceneNum} sx={{ mb: 2, p: 1.5, backgroundColor: '#fff', borderRadius: 1, border: '1px solid #E0DCD4' }}>
                      <Typography variant="caption" sx={{ color: '#5D4037', fontWeight: 600, display: 'block', mb: 0.5 }}>
                        Scene {sceneNum}:
                      </Typography>
                      <Typography 
                        variant="caption" 
                        sx={{ 
                          color: '#2C2416', 
                          fontFamily: 'monospace',
                          fontSize: '0.75rem',
                          whiteSpace: 'pre-wrap',
                          wordBreak: 'break-word',
                          display: 'block',
                        }}
                      >
                        {prompt.length > 200 ? `${prompt.substring(0, 200)}...` : prompt}
                      </Typography>
                    </Box>
                  ))}
              </Box>
            )}
          </Box>
        )}
        
        {state.hdVideoGenerationStatus === 'completed' && (
          <Alert severity="success" sx={{ mt: 2 }}>
            HD video generation complete! {state.sceneHdVideos?.size || 0} of {state.outlineScenes?.length || 0} scenes were approved.
          </Alert>
        )}
      </Box>

      {approvalModal && state.outlineScenes && (
        <SceneVideoApproval
          open={approvalModal.open}
          sceneNumber={approvalModal.sceneNumber}
          sceneTitle={approvalModal.sceneTitle}
          totalScenes={state.outlineScenes.length}
          videoUrl={approvalModal.videoUrl}
          promptUsed={approvalModal.promptUsed}
          onApprove={handleApprove}
          onReject={handleReject}
          onRegenerate={handleRegenerate}
          isRegenerating={regeneratingScene === approvalModal.sceneNumber}
          onClose={() => {
            if (!isGeneratingHdVideo && !regeneratingScene) {
              setApprovalModal(null);
              state.setHdVideoGenerationStatus('paused');
            }
          }}
        />
      )}
    </>
  );
};

