import React, { useEffect, useRef, useCallback, useState } from "react";
import { useTVModeStore, selectCurrentScene, selectSceneDuration, selectIsLastScene, selectNextSceneReady, selectCurrentSceneImageReady, selectIsWaitingForImage, selectNextScene, } from "../../stores/tvModeStore";
import { TVModePlayer } from "./TVModePlayer";
import { TVModeControls } from "./TVModeControls";
import { TVModeSettings } from "./TVModeSettings";
import { TVModeEndScreen } from "./TVModeEndScreen";
import { TVModeChapterTransition } from "./TVModeChapterTransition";
import { useTTSPlayback } from "../../hooks/useTTSPlayback";
export const TVModeContainer = ({ onGenerateNext, onEnsureImage, onContinueChapter, onSyncOutline, }) => {
    const containerRef = useRef(null);
    const controlsTimerRef = useRef(null);
    const sceneTimerRef = useRef(null);
    const prefetchInFlightRef = useRef(false);
    const [showChapterTransition, setShowChapterTransition] = useState(false);
    const [waitingForTTS, setWaitingForTTS] = useState(false);
    const [waitingForNextScene, setWaitingForNextScene] = useState(false);
    const { isActive, isPlaying, currentSceneIndex, scenes, controlsVisible, showSettings, showEndScreen, isPrefetching, isStoryComplete, isLoadingNextChapter, chapterNumber, settings, exitTVMode, togglePlay, nextScene, prevScene, goToScene, showControls, hideControls, setShowSettings, addScene, setPrefetching, setPrefetchError, setFullscreen, setLoadingNextChapter, startNextChapter, } = useTVModeStore();
    const currentScene = useTVModeStore(selectCurrentScene);
    const nextSceneData = useTVModeStore(selectNextScene);
    const sceneDuration = useTVModeStore(selectSceneDuration);
    const isLastScene = useTVModeStore(selectIsLastScene);
    const nextSceneReady = useTVModeStore(selectNextSceneReady);
    const currentImageReady = useTVModeStore(selectCurrentSceneImageReady);
    const isWaitingForImage = useTVModeStore(selectIsWaitingForImage);
    // Callback when TTS finishes speaking a scene - advance when next scene is ready
    // TTS drives continuous narration, but waits for next scene (content + image) before advancing
    const handleSceneNarrationEnd = useCallback(() => {
        console.log("[TV Mode] TTS narration finished for current scene");
        setWaitingForTTS(false);
        if (isLastScene) {
            // On last scene - check if we should generate more or end
            if (scenes.length < 24 && !isPrefetching && !isStoryComplete && settings.autoGenerateScenes) {
                // More scenes can be generated - set waiting state, prefetch effect will handle generation
                console.log("[TV Mode] Last scene finished, waiting for new scene generation...");
                setWaitingForNextScene(true);
            }
            else if (!isStoryComplete && !isPrefetching) {
                nextScene(); // This will trigger end screen
            }
        }
        else if (nextSceneReady) {
            // Next scene is ready (content + image) - advance immediately
            console.log("[TV Mode] Next scene ready, advancing...");
            setWaitingForNextScene(false);
            nextScene();
        }
        else {
            // Next scene exists but not ready yet - wait for it
            console.log("[TV Mode] Waiting for next scene to be ready (image generating)...");
            setWaitingForNextScene(true);
        }
    }, [isLastScene, scenes.length, isPrefetching, isStoryComplete, nextSceneReady, nextScene, settings.autoGenerateScenes]);
    // TTS Playback Integration
    const { ttsEnabled, setTTSEnabled, isSpeaking, isPaused: ttsPaused, isSupported: ttsSupported, voices, voiceConfig, setVoiceConfig, stopSpeaking, pauseSpeaking, resumeSpeaking, } = useTTSPlayback({
        isActive,
        isPlaying,
        currentScene,
        currentSceneIndex,
        scenes,
        onSceneNarrationEnd: handleSceneNarrationEnd,
    });
    // Enter fullscreen on mount
    useEffect(() => {
        if (isActive && containerRef.current) {
            const enterFullscreen = async () => {
                try {
                    await containerRef.current?.requestFullscreen();
                    setFullscreen(true);
                }
                catch (err) {
                    console.warn("Could not enter fullscreen:", err);
                }
            };
            enterFullscreen();
        }
        return () => {
            if (document.fullscreenElement) {
                document.exitFullscreen().catch(() => { });
            }
        };
    }, [isActive, setFullscreen]);
    // Handle fullscreen change
    useEffect(() => {
        const handleFullscreenChange = () => {
            if (!document.fullscreenElement && isActive) {
                setFullscreen(false);
            }
        };
        document.addEventListener("fullscreenchange", handleFullscreenChange);
        return () => {
            document.removeEventListener("fullscreenchange", handleFullscreenChange);
        };
    }, [isActive, setFullscreen]);
    // Auto-hide controls timer
    const resetControlsTimer = useCallback(() => {
        if (controlsTimerRef.current) {
            clearTimeout(controlsTimerRef.current);
        }
        showControls();
        if (isPlaying && !showSettings) {
            controlsTimerRef.current = window.setTimeout(() => {
                hideControls();
            }, settings.autoHideDelay);
        }
    }, [isPlaying, showSettings, settings.autoHideDelay, showControls, hideControls]);
    // Track when TTS starts speaking to set waitingForTTS
    useEffect(() => {
        if (ttsEnabled && isSpeaking && currentScene?.narration) {
            setWaitingForTTS(true);
        }
    }, [ttsEnabled, isSpeaking, currentScene?.narration]);
    // Reset waitingForTTS when scene changes, TTS disabled, or playback stops
    useEffect(() => {
        if (!ttsEnabled || !isPlaying) {
            setWaitingForTTS(false);
        }
    }, [ttsEnabled, isPlaying]);
    // Reset waitingForTTS when scene changes (new scene means new narration)
    useEffect(() => {
        setWaitingForTTS(false);
    }, [currentSceneIndex]);
    // Reset waitingForNextScene when scene changes
    useEffect(() => {
        setWaitingForNextScene(false);
    }, [currentSceneIndex]);
    // Advance to next scene when it becomes ready (while we're waiting for it)
    useEffect(() => {
        if (!waitingForNextScene || !isPlaying)
            return;
        if (nextSceneReady) {
            // Next scene is now ready - advance!
            console.log("[TV Mode] Next scene now ready, advancing...");
            setWaitingForNextScene(false);
            nextScene();
        }
    }, [waitingForNextScene, nextSceneReady, isPlaying, nextScene]);
    // Scene auto-advance timer - TTS drives the flow when enabled, timer only for non-TTS mode
    useEffect(() => {
        if (sceneTimerRef.current) {
            clearTimeout(sceneTimerRef.current);
            sceneTimerRef.current = null;
        }
        // Don't start timer if story is complete or chapter transition is showing
        if (isStoryComplete || showChapterTransition) {
            return;
        }
        // When TTS is enabled, let TTS drive scene advancement (via onSceneNarrationEnd callback)
        // TTS finishes speaking, then waits for next scene to be ready before advancing
        if (ttsEnabled && currentScene?.narration) {
            // TTS is controlling the flow - it will call onSceneNarrationEnd when done
            if (isSpeaking || waitingForTTS) {
                console.log("[TV Mode] TTS driving flow, narration in progress...");
                return;
            }
            // Waiting for next scene to be ready (image generating)
            if (waitingForNextScene) {
                console.log("[TV Mode] TTS finished, waiting for next scene to be ready...");
                return;
            }
            // TTS enabled but not speaking yet - let auto-speak effect handle it
            return;
        }
        // Non-TTS mode: use timer and wait for images
        // Don't start timer if current scene's image isn't ready yet (visual-first mode)
        if (!currentImageReady && currentScene) {
            return;
        }
        if (isPlaying && currentScene && !showEndScreen) {
            sceneTimerRef.current = window.setTimeout(() => {
                if (isLastScene) {
                    // Only auto-generate if setting is enabled
                    if (scenes.length < 24 && !isPrefetching && !isStoryComplete && settings.autoGenerateScenes) {
                        // Trigger prefetch for more scenes
                        handlePrefetch();
                    }
                    else if (!isStoryComplete && !isPrefetching) {
                        // Only advance to end screen if not prefetching and story not complete
                        nextScene(); // This will trigger end screen via the store
                    }
                    // If story is complete or prefetching, wait - chapter transition or prefetch will handle it
                }
                else if (nextSceneReady) {
                    // Only advance if next scene's image is ready
                    nextScene();
                }
                // If next scene isn't ready, timer will be reset by the effect
                // and we'll wait for the image to be ready
            }, sceneDuration);
        }
        return () => {
            if (sceneTimerRef.current) {
                clearTimeout(sceneTimerRef.current);
            }
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps -- handlePrefetch and nextScene are stable callbacks
    }, [isPlaying, currentSceneIndex, currentScene, sceneDuration, isLastScene, showEndScreen, nextSceneReady, currentImageReady, isStoryComplete, showChapterTransition, isPrefetching, scenes.length, ttsEnabled, isSpeaking, waitingForTTS, waitingForNextScene, settings.autoGenerateScenes]);
    // Trigger image generation for current scene if needed
    useEffect(() => {
        if (!currentScene || !onEnsureImage)
            return;
        const hasImage = Boolean(currentScene.image_url || currentScene.image);
        if (!hasImage && (currentScene.imageStatus === "pending" || currentScene.imageStatus === "generating")) {
            onEnsureImage(currentScene);
        }
    }, [currentScene?.idx, currentScene?.imageStatus, onEnsureImage]);
    // Trigger image generation for next scene (prefetch image while current scene plays)
    useEffect(() => {
        if (!nextSceneData || !onEnsureImage)
            return;
        const hasImage = Boolean(nextSceneData.image_url || nextSceneData.image);
        if (!hasImage && (nextSceneData.imageStatus === "pending" || nextSceneData.imageStatus === "generating")) {
            onEnsureImage(nextSceneData);
        }
    }, [nextSceneData?.idx, nextSceneData?.imageStatus, onEnsureImage]);
    // Prefetch next scene
    const handlePrefetch = useCallback(async () => {
        // Don't prefetch if story is already complete or at max scenes
        if (prefetchInFlightRef.current || isPrefetching || isStoryComplete || scenes.length >= 24)
            return;
        prefetchInFlightRef.current = true;
        setPrefetching(true);
        setPrefetchError(null);
        try {
            console.log("[TV Mode] Starting scene generation...");
            const newScene = await onGenerateNext();
            if (newScene) {
                addScene(newScene);
                console.log("[TV Mode] New scene generated successfully:", newScene.idx);
                // Sync outline after successful scene generation
                if (onSyncOutline) {
                    try {
                        await onSyncOutline();
                        console.log("[TV Mode] Outline synced after scene generation");
                    }
                    catch (syncError) {
                        console.warn("[TV Mode] Failed to sync outline:", syncError);
                    }
                }
            }
            // If null returned, story is complete (handled by caller)
        }
        catch (error) {
            console.error("[TV Mode] Scene generation failed:", error);
            setPrefetchError(error.message || "Failed to generate next scene");
        }
        finally {
            setPrefetching(false);
            prefetchInFlightRef.current = false;
        }
    }, [isPrefetching, isStoryComplete, scenes.length, onGenerateNext, addScene, setPrefetching, setPrefetchError, onSyncOutline]);
    // Trigger prefetch when playing and near end (but not if story is complete or auto-generate is disabled)
    useEffect(() => {
        if (isPlaying && isLastScene && scenes.length < 24 && !isPrefetching && !isStoryComplete && settings.autoGenerateScenes) {
            handlePrefetch();
        }
    }, [isPlaying, isLastScene, scenes.length, isPrefetching, isStoryComplete, handlePrefetch, settings.autoGenerateScenes]);
    // Show chapter transition when story is complete (saga mode)
    useEffect(() => {
        if (!isStoryComplete || !settings.sagaMode || !onContinueChapter) {
            setShowChapterTransition(false);
            return;
        }
        // Only show transition when we're on the last scene
        if (!isLastScene) {
            setShowChapterTransition(false);
            return;
        }
        // Show the chapter transition screen with countdown
        setShowChapterTransition(true);
    }, [isStoryComplete, settings.sagaMode, isLastScene, onContinueChapter]);
    // Handle continuing to next chapter (called from transition screen)
    const handleContinueToNextChapter = useCallback(async () => {
        if (!onContinueChapter || isLoadingNextChapter)
            return;
        console.log(`[TV Mode] Chapter ${chapterNumber} complete, loading next chapter...`);
        setLoadingNextChapter(true);
        try {
            const chapterData = await onContinueChapter();
            if (chapterData) {
                setShowChapterTransition(false);
                startNextChapter(chapterData.sessionId, chapterData.title, chapterData.scenes, chapterData.chapterNumber);
                console.log(`[TV Mode] Started chapter ${chapterData.chapterNumber}: ${chapterData.title}`);
            }
            else {
                // No more chapters available
                setLoadingNextChapter(false);
                setShowChapterTransition(false);
            }
        }
        catch (error) {
            console.error('[TV Mode] Failed to continue to next chapter:', error);
            setLoadingNextChapter(false);
            setShowChapterTransition(false);
        }
    }, [onContinueChapter, isLoadingNextChapter, chapterNumber, setLoadingNextChapter, startNextChapter]);
    // Handle canceling the chapter transition
    const handleCancelChapterTransition = useCallback(() => {
        setShowChapterTransition(false);
        exitTVMode();
    }, [exitTVMode]);
    // Keyboard controls
    useEffect(() => {
        const handleKeyDown = (e) => {
            // Don't handle if settings panel is open and it's an input
            if (showSettings && e.target instanceof HTMLInputElement)
                return;
            switch (e.key) {
                case "Escape":
                    if (showSettings) {
                        setShowSettings(false);
                    }
                    else {
                        exitTVMode();
                    }
                    break;
                case " ":
                    e.preventDefault();
                    togglePlay();
                    resetControlsTimer();
                    break;
                case "ArrowRight":
                case "l":
                case "L":
                    nextScene();
                    resetControlsTimer();
                    break;
                case "ArrowLeft":
                case "j":
                case "J":
                    prevScene();
                    resetControlsTimer();
                    break;
                case "f":
                case "F":
                    if (document.fullscreenElement) {
                        document.exitFullscreen();
                    }
                    else {
                        containerRef.current?.requestFullscreen();
                    }
                    break;
                default:
                    resetControlsTimer();
            }
        };
        if (isActive) {
            window.addEventListener("keydown", handleKeyDown);
        }
        return () => {
            window.removeEventListener("keydown", handleKeyDown);
        };
    }, [isActive, showSettings, exitTVMode, togglePlay, nextScene, prevScene, resetControlsTimer, setShowSettings]);
    // Mouse/touch handlers
    const handleMouseMove = useCallback(() => {
        resetControlsTimer();
    }, [resetControlsTimer]);
    const handleClick = useCallback((e) => {
        // Don't toggle if clicking on controls
        if (e.target.closest(".tv-controls"))
            return;
        resetControlsTimer();
    }, [resetControlsTimer]);
    // Touch swipe handling
    const touchStartX = useRef(0);
    const handleTouchStart = useCallback((e) => {
        touchStartX.current = e.touches[0].clientX;
    }, []);
    const handleTouchEnd = useCallback((e) => {
        const deltaX = e.changedTouches[0].clientX - touchStartX.current;
        const minSwipeDistance = 50;
        if (Math.abs(deltaX) > minSwipeDistance) {
            if (deltaX > 0) {
                prevScene();
            }
            else {
                nextScene();
            }
        }
        resetControlsTimer();
    }, [prevScene, nextScene, resetControlsTimer]);
    if (!isActive)
        return null;
    return (<div ref={containerRef} className="tv-mode-container" onMouseMove={handleMouseMove} onClick={handleClick} onTouchStart={handleTouchStart} onTouchEnd={handleTouchEnd}>
      <TVModePlayer scene={currentScene} isTransitioning={false} transitionDuration={settings.transitionDuration} isImageLoading={!currentImageReady || isWaitingForImage} isPrefetching={isPrefetching}/>

      <TVModeControls visible={controlsVisible} isPlaying={isPlaying} currentIndex={currentSceneIndex} totalScenes={scenes.length} isPrefetching={isPrefetching} isWaitingForNextImage={!isLastScene && !nextSceneReady && isPlaying} onTogglePlay={togglePlay} onPrev={prevScene} onNext={() => {
            if (isLastScene && scenes.length < 24) {
                handlePrefetch();
            }
            nextScene();
        }} onExit={exitTVMode} onGoToScene={goToScene} onShowSettings={() => setShowSettings(true)} ttsEnabled={ttsEnabled} ttsSupported={ttsSupported} isSpeaking={isSpeaking} onToggleTTS={() => setTTSEnabled(!ttsEnabled)}/>

      {showSettings && (<TVModeSettings onClose={() => setShowSettings(false)} ttsEnabled={ttsEnabled} setTTSEnabled={setTTSEnabled} ttsSupported={ttsSupported} voices={voices} voiceConfig={voiceConfig} setVoiceConfig={setVoiceConfig}/>)}

      {/* Chapter Transition Screen (Saga Mode) */}
      {showChapterTransition && settings.sagaMode && onContinueChapter && (<TVModeChapterTransition onContinue={handleContinueToNextChapter} onCancel={handleCancelChapterTransition} nextChapterTitle={`Chapter ${chapterNumber + 1}`} countdown={5}/>)}

      {/* End Screen (when not in saga mode or saga mode disabled) */}
      {showEndScreen && !showChapterTransition && (<TVModeEndScreen onRestart={() => goToScene(0)} onExit={exitTVMode} onContinue={scenes.length < 24 ? handlePrefetch : undefined}/>)}

      <style>{`
        .tv-mode-container {
          position: fixed;
          inset: 0;
          background: #000;
          z-index: 9999;
          display: flex;
          flex-direction: column;
          user-select: none;
          overflow: hidden;
        }

        @media (prefers-reduced-motion: reduce) {
          .tv-mode-container * {
            animation: none !important;
            transition: none !important;
          }
        }
      `}</style>
    </div>);
};
export default TVModeContainer;
