<script lang="ts">
  import { onMount } from 'svelte';
  import ContinuousVideoPlayer from './ContinuousVideoPlayer.svelte';
  import NarrativeDisplay from './NarrativeDisplay.svelte';
  import ChoiceInterface from './ChoiceInterface.svelte';
  import SoraGenerator from './SoraGenerator.svelte';
  import { generateNarrative, buildSoraPrompt } from '$lib/api/openai';
  import {
    apiKey,
    currentScene,
    previousFinalFrame,
    addScene,
    updateCurrentScene,
    buildStoryContextText,
    setGenerating,
    setGenerationProgress,
    setGenerationError,
    isGenerating
  } from '$lib/stores/story';
  import type { StoryChoice, StoryScene, SoraGenerationParams } from '$lib/types';

  export let onError: ((error: string) => void) | undefined = undefined;

  let soraGenerator: any;
  let waitingForVideo = false;
  let showChoices = false;
  let currentVideoUrl: string | undefined;

  onMount(() => {
    // Start the adventure automatically
    startAdventure();
  });

  async function startAdventure() {
    if (!$apiKey) {
      const error = 'API key not set';
      setGenerationError(error);
      onError?.(error);
      return;
    }

    setGenerating(true);
    setGenerationError(null);

    try {
      // Generate the first scene
      const narrative = await generateNarrative($apiKey, {
        storyContext: '',
        isFirstScene: true
      });

      // Create the first scene
      const scene: StoryScene = {
        id: `scene-${Date.now()}`,
        narrative: narrative.narrative,
        choices: narrative.choices,
        timestamp: Date.now()
      };

      addScene(scene);

      // Generate the first video
      await generateVideoForCurrentScene(narrative.sceneDescription);

    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : 'Failed to start adventure';
      setGenerationError(errorMsg);
      onError?.(errorMsg);
      setGenerating(false);
    }
  }

  async function generateVideoForCurrentScene(sceneDescription: string) {
    if (!$apiKey || !soraGenerator) return;

    waitingForVideo = true;
    showChoices = false;

    try {
      // Build the Sora prompt with context if available
      const storyContext = buildStoryContextText();
      const soraPrompt = buildSoraPrompt(sceneDescription, storyContext);

      // Create generation parameters
      const params: SoraGenerationParams = {
        prompt: soraPrompt,
        size: '1280x720',
        seconds: 8,
        model: 'sora-2',
        inputReference: $previousFinalFrame || undefined
      };

      // Trigger video generation
      await soraGenerator.generate();

    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : 'Video generation failed';
      setGenerationError(errorMsg);
      onError?.(errorMsg);
      setGenerating(false);
      waitingForVideo = false;
    }
  }

  function handleVideoGenerated(event: CustomEvent<any>) {
    const result = event.detail;

    // Update current scene with video URL
    updateCurrentScene({ videoUrl: result.videoUrl });
    currentVideoUrl = result.videoUrl;

    waitingForVideo = false;
    setGenerating(false);
  }

  function handleVideoEnd(finalFrame: Blob) {
    // Store the final frame for continuity
    updateCurrentScene({ finalFrame });

    // Show choices after video ends
    showChoices = true;
  }

  async function handleChoiceSelected(choice: StoryChoice) {
    if (!$apiKey || $isGenerating) return;

    setGenerating(true);
    setGenerationError(null);
    showChoices = false;

    try {
      // Generate the next scene based on the choice
      const storyContext = buildStoryContextText();
      const narrative = await generateNarrative($apiKey, {
        storyContext,
        userChoice: choice.text,
        isFirstScene: false
      });

      // Create the new scene
      const scene: StoryScene = {
        id: `scene-${Date.now()}`,
        narrative: narrative.narrative,
        choices: narrative.choices,
        timestamp: Date.now()
      };

      addScene(scene);

      // Generate video for the new scene
      await generateVideoForCurrentScene(narrative.sceneDescription);

    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : 'Failed to continue story';
      setGenerationError(errorMsg);
      onError?.(errorMsg);
      setGenerating(false);
    }
  }

  function handleVideoError(error: string) {
    setGenerationError(error);
    onError?.(error);
  }

  function handleProgress(progress: number) {
    setGenerationProgress(progress);
  }

  function handleGenerationError(error: string) {
    setGenerationError(error);
    onError?.(error);
    setGenerating(false);
  }

  // Create Sora params for the generator component
  $: soraParams = $currentScene ? {
    prompt: buildSoraPrompt($currentScene.narrative, buildStoryContextText()),
    size: '1280x720',
    seconds: 8,
    model: 'sora-2',
    inputReference: $previousFinalFrame || undefined
  } as SoraGenerationParams : null;
</script>

<div class="story-engine">
  {#if $currentScene}
    <!-- Video Player -->
    <div class="video-section">
      <ContinuousVideoPlayer
        videoUrl={currentVideoUrl}
        onVideoEnd={handleVideoEnd}
        onError={handleVideoError}
      />
    </div>

    <!-- Narrative Display -->
    <NarrativeDisplay
      narrative={$currentScene.narrative}
      isVisible={!$isGenerating}
    />

    <!-- Sora Generator (hidden UI, controlled programmatically) -->
    {#if $apiKey && soraParams}
      <SoraGenerator
        bind:this={soraGenerator}
        apiKey={$apiKey}
        params={soraParams}
        onVideoGenerated={handleVideoGenerated}
        onProgress={handleProgress}
        onError={handleGenerationError}
      />
    {/if}

    <!-- Choices (shown after video ends) -->
    {#if showChoices && !$isGenerating}
      <ChoiceInterface
        choices={$currentScene.choices}
        onChoiceSelected={handleChoiceSelected}
        disabled={$isGenerating}
      />
    {/if}
  {:else if !$isGenerating}
    <div class="loading">
      <p>Initializing adventure...</p>
    </div>
  {/if}
</div>

<style>
  .story-engine {
    max-width: 1280px;
    margin: 0 auto;
    padding: 1rem;
  }

  .video-section {
    margin-bottom: 1rem;
  }

  .loading {
    text-align: center;
    padding: 4rem 2rem;
    color: #666;
  }

  .loading p {
    font-size: 1.1rem;
    margin: 0;
  }

  @media (max-width: 768px) {
    .story-engine {
      padding: 0.5rem;
    }
  }
</style>
