import { useState, useEffect, useRef, useCallback, useMemo } from "react";
import LoadingScreen from "./components/LoadingScreen";
import CaptioningView from "./components/CaptioningView";
import WelcomeScreen from "./components/WelcomeScreen";
import SourceSelector from "./components/SourceSelector";
import type { AppState, VideoSource } from "./types";

export default function App() {
  const [appState, setAppState] = useState<AppState>("source-selection");
  const [videoSource, setVideoSource] = useState<VideoSource | null>(null);
  const [isVideoReady, setIsVideoReady] = useState(false);
  const videoRef = useRef<HTMLVideoElement | null>(null);

  const handleSourceSelected = useCallback((source: VideoSource) => {
    setVideoSource(source);
    setAppState("welcome");
  }, []);

  const handleBackToSourceSelection = useCallback(() => {
    // Clean up current source
    if (videoSource?.stream) {
      videoSource.stream.getTracks().forEach(track => track.stop());
    }
    if (videoSource?.url && videoSource.type === "upload") {
      URL.revokeObjectURL(videoSource.url);
    }
    setVideoSource(null);
    setIsVideoReady(false);
    setAppState("source-selection");
  }, [videoSource]);

  const handleStart = useCallback(() => {
    setAppState("loading");
  }, []);

  const handleLoadingComplete = useCallback(() => {
    setAppState("captioning");
  }, []);

  const playVideo = useCallback(async (video: HTMLVideoElement) => {
    try {
      await video.play();
    } catch (error) {
      console.error("Failed to play video:", error);
    }
  }, []);

  const setupVideo = useCallback(
    (video: HTMLVideoElement, source: VideoSource) => {
      // Reset video element
      video.srcObject = null;
      video.src = "";
      video.load();

      if (source.stream) {
        // Stream-based sources (webcam, screen share)
        video.srcObject = source.stream;
      } else if (source.url) {
        // URL-based sources (upload, examples)
        video.src = source.url;
        video.loop = true; // Loop for uploaded/example videos
      }

      const handleCanPlay = () => {
        setIsVideoReady(true);
        playVideo(video);
      };

      video.addEventListener("canplay", handleCanPlay, { once: true });

      // Handle stream ended (e.g., user stops screen sharing)
      if (source.stream) {
        const track = source.stream.getVideoTracks()[0];
        if (track) {
          track.onended = () => {
            handleBackToSourceSelection();
          };
        }
      }

      return () => {
        video.removeEventListener("canplay", handleCanPlay);
      };
    },
    [playVideo, handleBackToSourceSelection],
  );

  useEffect(() => {
    if (videoSource && videoRef.current) {
      const video = videoRef.current;
      const cleanup = setupVideo(video, videoSource);
      return cleanup;
    }
  }, [videoSource, setupVideo]);

  const videoBlurState = useMemo(() => {
    switch (appState) {
      case "source-selection":
        return "blur(20px) brightness(0.2) saturate(0.5)";
      case "welcome":
        return "blur(12px) brightness(0.3) saturate(0.7)";
      case "loading":
        return "blur(8px) brightness(0.4) saturate(0.8)";
      case "captioning":
        return "none";
      default:
        return "blur(20px) brightness(0.2) saturate(0.5)";
    }
  }, [appState]);

  const getSourceLabel = () => {
    if (!videoSource) return null;
    switch (videoSource.type) {
      case "webcam":
        return "Webcam";
      case "screen":
        return "Screen Share";
      case "upload":
        return videoSource.name || "Uploaded Video";
      case "example":
        return videoSource.name || "Example Video";
    }
  };

  return (
    <div className="App relative h-screen overflow-hidden bg-[#FFFAEB]">
      <div className="absolute inset-0 bg-[#FFFAEB]" />

      {videoSource && (
        <video
          ref={videoRef}
          autoPlay
          muted
          playsInline
          className="absolute inset-0 w-full h-full object-cover transition-all duration-1000 ease-out"
          style={{
            filter: videoBlurState,
            opacity: isVideoReady ? 1 : 0,
          }}
        />
      )}

      {appState !== "captioning" && appState !== "source-selection" && (
        <div className="absolute inset-0 bg-[#FFFAEB]/90 backdrop-blur-sm" />
      )}

      {appState === "source-selection" && (
        <SourceSelector onSourceSelected={handleSourceSelected} />
      )}

      {appState === "welcome" && (
        <WelcomeScreen 
          onStart={handleStart} 
          onBack={handleBackToSourceSelection}
          sourceLabel={getSourceLabel() ?? undefined}
        />
      )}

      {appState === "loading" && (
        <LoadingScreen onComplete={handleLoadingComplete} />
      )}

      {appState === "captioning" && (
        <CaptioningView 
          videoRef={videoRef} 
          videoSource={videoSource}
          onChangeSource={handleBackToSourceSelection}
        />
      )}
    </div>
  );
}
