// App — thin UI shell. All logic lives in GameEngine.
const { useState, useEffect, useRef, useCallback } = React;

function MusicPlayer() {
    const audioRef = useRef(null);
    const [playing, setPlaying] = useState(true);
    const fadeTimerRef = useRef(null);

    useEffect(() => {
        const audio = audioRef.current;
        if (!audio) return;

        const FADE_DURATION = 3; // seconds
        const MAX_VOLUME = 0.8;
        audio.volume = MAX_VOLUME;

        // Crossfade loop: fade out near end, restart with fade in
        const handleTimeUpdate = () => {
            const timeLeft = audio.duration - audio.currentTime;
            if (timeLeft <= FADE_DURATION && timeLeft > 0) {
                audio.volume = Math.max(0, (timeLeft / FADE_DURATION) * MAX_VOLUME);
            }
        };

        const handleEnded = () => {
            audio.currentTime = 0;
            audio.volume = 0;
            audio.play().catch(() => {});
            // Fade in
            const step = 50; // ms
            const increment = MAX_VOLUME / (FADE_DURATION * 1000 / step);
            clearInterval(fadeTimerRef.current);
            fadeTimerRef.current = setInterval(() => {
                if (audio.volume + increment >= MAX_VOLUME) {
                    audio.volume = MAX_VOLUME;
                    clearInterval(fadeTimerRef.current);
                } else {
                    audio.volume += increment;
                }
            }, step);
        };

        audio.addEventListener('timeupdate', handleTimeUpdate);
        audio.addEventListener('ended', handleEnded);

        // Sync icon when audio state changes (e.g. via Media Session keys)
        const onPlay = () => setPlaying(true);
        const onPause = () => setPlaying(false);
        audio.addEventListener('play', onPlay);
        audio.addEventListener('pause', onPause);

        // Register Media Session handlers (Mac keyboard play/pause)
        if ('mediaSession' in navigator) {
            navigator.mediaSession.metadata = new MediaMetadata({ title: 'RISK', artist: 'Soundtrack' });
            navigator.mediaSession.setActionHandler('play', () => audio.play());
            navigator.mediaSession.setActionHandler('pause', () => audio.pause());
        }

        // Try autoplay immediately — if blocked, wait for user to click the music button
        audio.play().catch(() => {
            setPlaying(false);
        });

        return () => {
            audio.removeEventListener('timeupdate', handleTimeUpdate);
            audio.removeEventListener('ended', handleEnded);
            audio.removeEventListener('play', onPlay);
            audio.removeEventListener('pause', onPause);
            clearInterval(fadeTimerRef.current);
        };
    }, []);

    const toggle = useCallback(() => {
        const audio = audioRef.current;
        if (!audio) return;
        if (playing) {
            audio.pause();
        } else {
            audio.volume = 0.8;
            audio.play().catch(() => {});
        }
        setPlaying(!playing);
    }, [playing]);

    return (
        <>
            <audio ref={audioRef} src="/assets/soundtrack.mp3" />
            <button
                className="music-btn"
                onClick={toggle}
                title={playing ? 'Mute' : 'Unmute'}
                style={{ color: playing ? 'var(--color-success)' : 'var(--color-danger)' }}
            >
                {playing ? (
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                        <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="currentColor" stroke="none" />
                        <path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
                        <path d="M19.07 4.93a10 10 0 0 1 0 14.14" />
                    </svg>
                ) : (
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                        <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="currentColor" stroke="none" />
                        <line x1="23" y1="9" x2="17" y2="15" />
                        <line x1="17" y1="9" x2="23" y2="15" />
                    </svg>
                )}
            </button>
        </>
    );
}

function AbandonConfirmModal({ onConfirm, onCancel }) {
    return (
        <div className="abandon-overlay" onClick={onCancel}>
            <div className="abandon-modal" onClick={(e) => e.stopPropagation()}>
                <div className="abandon-icon">&#9888;</div>
                <h3>Active game in progress</h3>
                <p>Starting a new game will count your current game as <strong>a defeat</strong>. Your leader will be remembered as having abandoned their post.</p>
                <div className="abandon-buttons">
                    <button className="abandon-btn abandon-btn-cancel" onClick={onCancel}>
                        Continue current game
                    </button>
                    <button className="abandon-btn abandon-btn-confirm" onClick={onConfirm}>
                        Abandon &amp; start new game
                    </button>
                </div>
            </div>
        </div>
    );
}

function App() {
    const [, forceUpdate] = useState(0);
    const [settingsPage, setSettingsPage] = useState(null);
    const [showSettingsPanel, setShowSettingsPanel] = useState(false);
    const [historyOpen, setHistoryOpen] = useState(false);
    const [abandonAction, setAbandonAction] = useState(null);

    // Create engine once
    const engineRef = useRef(null);
    if (!engineRef.current) {
        engineRef.current = new GameEngine({ firebaseClient, claudeClient });
    }
    const engine = engineRef.current;

    // Subscribe to engine state changes → trigger re-render
    useEffect(() => {
        const unsub = engine.subscribe(() => forceUpdate(n => n + 1));
        // Defer one tick: the click that triggers the paywall bubbles up to the
        // sidebar's dismiss handler in the same event, which would close it
        // immediately. Opening on the next tick wins over that dismiss.
        engine.onPaywallHit = () => setTimeout(() => { setShowSettingsPanel(true); setSettingsPage('subscription'); }, 0);
        engine.initialize();
        return () => { unsub(); engine.destroy(); };
    }, []);

    // Read state from engine
    const { firebaseReady, authChecked, gameLoaded, user, game, isAiLoading, gameList, currentGameId } = engine.getState();
    const { gamePhase, chatHistory, choices, turn, playerTheme } = game;

    const showScenarios = gameLoaded && turn === 0 && chatHistory.length === 0 && !isAiLoading;

    // Globe rotation: idle-rotate only when there's no game in progress
    // (scenario selection / fresh menu). Once a game exists it stays focused
    // and still — even behind a paywall or settings overlay — so opening one
    // mid-game doesn't make it drift.
    const gameInProgress = chatHistory.length > 0;
    const inGameView = !showScenarios && !showSettingsPanel && !settingsPage && gameInProgress;
    useEffect(() => {
        if (gameInProgress) window.stopGlobeRotation?.();
        else window.startGlobeRotation?.();
    }, [gameInProgress]);

    // Pulse the focused country while the GM is generating its response
    useEffect(() => {
        window.setGlobePulse?.(inGameView && isAiLoading);
    }, [inGameView, isAiLoading]);

    return (
        <div className="game-container">
            <GlobeBackground />
            {user && <LanguageSelector />}
            <div className={`app-layout${!user ? ' app-layout--blurred' : ''}`}>
                <button className="history-toggle" onClick={() => setHistoryOpen(!historyOpen)}>
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                        <line x1="3" y1="6" x2="21" y2="6"></line>
                        <line x1="3" y1="12" x2="21" y2="12"></line>
                        <line x1="3" y1="18" x2="21" y2="18"></line>
                    </svg>
                </button>

                {historyOpen && <div className="history-backdrop" onClick={() => setHistoryOpen(false)} />}

                <GameHistory
                    games={gameList}
                    currentGameId={currentGameId}
                    onSelectGame={(id) => {
                        if (engine.hasActiveGame() && id !== currentGameId) {
                            setAbandonAction({ type: 'switch', gameId: id });
                        } else {
                            engine.switchGame(id);
                        }
                        setHistoryOpen(false);
                    }}
                    onNewGame={() => {
                        if (engine.hasActiveGame()) {
                            setAbandonAction({ type: 'new' });
                        } else {
                            engine.newGame();
                        }
                        setHistoryOpen(false);
                    }}
                    onDeleteGame={(id) => engine.deleteGame(id)}
                    onDownload={() => engine.downloadGame()}
                    onSignOut={() => engine.signOut()}
                    user={user}
                    isOpen={historyOpen}
                    onSettingsPage={setSettingsPage}
                    onCloseSettings={() => setSettingsPage(null)}
                    settingsPage={settingsPage}
                    showSettings={showSettingsPanel}
                    onToggleSettings={setShowSettingsPanel}
                />

                {!showScenarios && !showSettingsPanel && (
                    <div className="leader-column">
                        {game.leaderCard && <LeaderCard leader={game.leaderCard} />}
                    </div>
                )}

                <Sidebar
                    chatHistory={chatHistory}
                    choices={choices}
                    isLoading={isAiLoading}
                    gameLoaded={gameLoaded}
                    onSendMessage={(msg) => engine.sendMessage(msg)}
                    onSelectChoice={(choice) => engine.selectChoice(choice)}
                    onRetry={() => engine.retryLastMessage()}
                    onRequestIntel={game.intelTurn !== turn ? () => engine.requestIntel() : null}
                    gamePhase={gamePhase}
                    epitaph={game.epitaph}
                    turn={turn}
                    onSelectScenario={(s) => engine.selectScenario(s)}
                    onCustomGame={() => engine.startCustomGame()}
                    playerTheme={playerTheme}
                    scenarioId={game.scenarioId}
                    gameId={currentGameId}
                    shareSummary={game.shareSummary}
                    settingsPage={settingsPage}
                    onCloseSettings={() => setSettingsPage(null)}
                    onDismissSettings={() => { setSettingsPage(null); setShowSettingsPanel(false); }}
                    gameList={gameList}
                    achievements={game.achievements}
                    onShowLadder={() => { setSettingsPage('ladder'); setShowSettingsPanel(true); }}
                    published={game.published}
                    customScenario={game.customScenario}
                />

            </div>

            {abandonAction && (
                <AbandonConfirmModal
                    onConfirm={async () => {
                        const action = abandonAction;
                        setAbandonAction(null);
                        await engine.abandonCurrentGame();
                        if (action.type === 'switch') {
                            engine.switchGame(action.gameId);
                        } else {
                            engine.newGame();
                        }
                    }}
                    onCancel={() => setAbandonAction(null)}
                />
            )}

            {firebaseReady && authChecked && !user && (
                <LoginOverlay onSignIn={(p) => engine.signIn(p)} isLoading={false} />
            )}

            {(!firebaseReady || (user && !gameLoaded)) && (
                <div className="login-overlay">
                    <div className="login-modal" style={{ padding: '60px 40px' }}>
                        <div className="loading-spinner" style={{ margin: '0 auto 16px', width: '32px', height: '32px' }}></div>
                        <div style={{ color: 'var(--color-text-muted)', fontSize: '14px' }}>Loading...</div>
                    </div>
                </div>
            )}
        </div>
    );
}
