import { useEffect } from 'react';

import { GameShellRuntime } from './components/game-shell/GameShellRuntime.tsx';
import { activateRosterCompanion, benchActiveCompanion } from './data/companionRoster';
import { syncGameStatePlayTime } from './data/runtimeStats';
import { useBackgroundMusic } from './hooks/useBackgroundMusic';
import { useCombatFlow } from './hooks/useCombatFlow';
import { useGameFlow } from './hooks/useGameFlow';
import { useGamePersistence } from './hooks/useGamePersistence';
import { useGameSettings } from './hooks/useGameSettings';
import { useNpcInteractionFlow } from './hooks/useNpcInteractionFlow';
import { useStoryGeneration } from './hooks/useStoryGeneration';

export default function App() {
  const {
    gameState,
    setGameState,
    bottomTab,
    setBottomTab,
    isMapOpen,
    setIsMapOpen,
    resetGame,
    handleCustomWorldSelect: selectCustomWorld,
    handleBackToWorldSelect: backToWorldSelect,
    handleCharacterSelect: selectCharacter,
  } = useGameFlow();

  const combatFlow = useCombatFlow({
    setGameState,
  });

  const storyFlow = useStoryGeneration({
    gameState,
    setGameState,
    buildResolvedChoiceState: combatFlow.buildResolvedChoiceState,
    playResolvedChoice: combatFlow.playResolvedChoice,
  });

  const { companionRenderStates, buildCompanionRenderStates } = useNpcInteractionFlow(gameState);
  const settings = useGameSettings();

  const persistence = useGamePersistence({
    gameState,
    bottomTab,
    currentStory: storyFlow.currentStory,
    isLoading: storyFlow.isLoading,
    setGameState,
    setBottomTab,
    hydrateStoryState: storyFlow.hydrateStoryState,
    resetStoryState: storyFlow.resetStoryState,
  });

  useBackgroundMusic({
    active: Boolean(gameState.playerCharacter && gameState.currentScene === 'Story'),
    volume: settings.musicVolume,
  });

  useEffect(() => {
    if (!gameState.playerCharacter || gameState.currentScene !== 'Story') {
      return;
    }

    const intervalId = window.setInterval(() => {
      setGameState(currentState => {
        if (!currentState.playerCharacter || currentState.currentScene !== 'Story') {
          return currentState;
        }

        return syncGameStatePlayTime(currentState);
      });
    }, 15000);

    return () => window.clearInterval(intervalId);
  }, [gameState.currentScene, gameState.playerCharacter, setGameState]);

  const handleCustomWorldSelect = (
    customWorldProfile: Parameters<typeof selectCustomWorld>[0],
  ) => {
    storyFlow.resetStoryState();
    selectCustomWorld(customWorldProfile);
  };

  const handleCharacterSelect = (
    character: Parameters<typeof selectCharacter>[0],
  ) => {
    storyFlow.resetStoryState();
    selectCharacter(character);
  };

  const handleBackToWorldSelect = () => {
    storyFlow.resetStoryState();
    backToWorldSelect();
  };

  const handleContinueGame = () => {
    persistence.continueSavedGame();
  };

  const handleStartNewGame = () => {
    persistence.clearSavedGame();
    storyFlow.resetStoryState();
    resetGame();
  };

  const handleSaveAndExit = () => {
    const syncedGameState = syncGameStatePlayTime(gameState);
    persistence.saveCurrentGame({
      gameState: syncedGameState,
      bottomTab,
      currentStory: storyFlow.currentStory,
    });
    storyFlow.resetStoryState();
    resetGame();
  };

  const handleBenchCompanion = (npcId: string) => {
    setGameState(currentState => benchActiveCompanion(currentState, npcId));
  };

  const handleActivateRosterCompanion = (npcId: string, swapNpcId?: string | null) => {
    setGameState(currentState => activateRosterCompanion(currentState, npcId, swapNpcId));
  };

  const gameShellSession = {
    gameState,
    currentStory: storyFlow.currentStory,
    isLoading: storyFlow.isLoading,
    aiError: storyFlow.aiError,
    bottomTab,
    setBottomTab,
    isMapOpen,
    setIsMapOpen,
  };

  const gameShellStory = {
    displayedOptions: storyFlow.displayedOptions,
    canRefreshOptions: storyFlow.canRefreshOptions,
    handleRefreshOptions: storyFlow.handleRefreshOptions,
    handleChoice: storyFlow.handleChoice,
    handleMapTravelToScene: storyFlow.travelToSceneFromMap,
    npcUi: storyFlow.npcUi,
    characterChatUi: storyFlow.characterChatUi,
    inventoryUi: storyFlow.inventoryUi,
    battleRewardUi: storyFlow.battleRewardUi,
    questUi: storyFlow.questUi,
    goalUi: storyFlow.goalUi,
  };

  const gameShellEntry = {
    hasSavedGame: persistence.hasSavedGame,
    handleContinueGame,
    handleStartNewGame,
    handleSaveAndExit,
    handleCustomWorldSelect,
    handleBackToWorldSelect,
    handleCharacterSelect,
  };

  const gameShellCompanions = {
    companionRenderStates,
    buildCompanionRenderStates,
    onBenchCompanion: handleBenchCompanion,
    onActivateRosterCompanion: handleActivateRosterCompanion,
  };

  const gameShellAudio = {
    musicVolume: settings.musicVolume,
    onMusicVolumeChange: settings.setMusicVolume,
  };

  return (
    <GameShellRuntime
      session={gameShellSession}
      story={gameShellStory}
      entry={gameShellEntry}
      companions={gameShellCompanions}
      audio={gameShellAudio}
    />
  );
}
