"use client";

import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { ArrowLeft, Scissors } from "lucide-react";

import { TrimmerExportSection } from "@/components/trimmer/TrimmerExportSection";
import { TrimmerStrip } from "@/components/trimmer/TrimmerStrip";
import { TrimmerUploadZone } from "@/components/trimmer/TrimmerUploadZone";
import { TrimmerVideoPreview } from "@/components/trimmer/TrimmerVideoPreview";
import {
  preloadFfmpegWorker,
  processTrimmedVideoInWorker,
} from "@/lib/ffmpeg-worker-client";
import type {
  AspectRatioPreset,
  CropBox,
  ExportFormat,
} from "@/lib/trimmer-types";
import { parseFfmpegProgress } from "@/lib/trimmer-utils";

const INITIAL_CROP: CropBox = { x: 0, y: 0, w: 320, h: 180 };

export default function VideoTrimmerPage() {
  const t = useTranslations("auto.appStudioTrimmerPage");
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
  const [videoUrl, setVideoUrl] = useState<string | null>(null);
  const [duration, setDuration] = useState(0);
  const [trimStart, setTrimStart] = useState(0);
  const [trimEnd, setTrimEnd] = useState(0);
  const [cropBox, setCropBox] = useState<CropBox>(INITIAL_CROP);
  const [aspectRatio, setAspectRatio] = useState<AspectRatioPreset>("free");
  const [displaySize, setDisplaySize] = useState({ width: 0, height: 0 });
  const [videoSize, setVideoSize] = useState({ width: 0, height: 0 });
  const [exportFormat, setExportFormat] = useState<ExportFormat>("mp4");
  const [isProcessing, setIsProcessing] = useState(false);
  const [progress, setProgress] = useState(0);
  const [outputUrl, setOutputUrl] = useState<string | null>(null);
  const [ffmpegReady, setFfmpegReady] = useState(false);
  const [ffmpegError, setFfmpegError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;

    preloadFfmpegWorker()
      .then(() => {
        if (!cancelled) setFfmpegReady(true);
      })
      .catch(() => {
        if (!cancelled) {
          setFfmpegError(t("ffmpegLoadError"));
        }
      });

    return () => {
      cancelled = true;
    };
  }, [t]);

  useEffect(() => {
    return () => {
      if (videoUrl) URL.revokeObjectURL(videoUrl);
      if (outputUrl) URL.revokeObjectURL(outputUrl);
    };
  }, [videoUrl, outputUrl]);

  const handleFileSelect = useCallback(
    (file: File) => {
      if (videoUrl) URL.revokeObjectURL(videoUrl);
      if (outputUrl) URL.revokeObjectURL(outputUrl);

      const url = URL.createObjectURL(file);
      setUploadedFile(file);
      setVideoUrl(url);
      setOutputUrl(null);
      setProgress(0);
      setTrimStart(0);
      setTrimEnd(0);
      setDuration(0);
      setCropBox(INITIAL_CROP);
    },
    [videoUrl, outputUrl]
  );

  const handleVideoMetadata = useCallback(
    (videoDuration: number, size: { width: number; height: number }) => {
      setDuration(videoDuration);
      setTrimStart(0);
      setTrimEnd(videoDuration);
      setVideoSize(size);
    },
    []
  );

  const handleTrimChange = useCallback((start: number, end: number) => {
    setTrimStart(Math.max(0, start));
    setTrimEnd(end);
  }, []);

  const handleProcess = useCallback(async () => {
    if (!uploadedFile || !ffmpegReady || displaySize.width <= 0) return;

    setIsProcessing(true);
    setProgress(0);
    if (outputUrl) URL.revokeObjectURL(outputUrl);
    setOutputUrl(null);

    const clipDuration = trimEnd - trimStart;

    try {
      const blob = await processTrimmedVideoInWorker({
        file: uploadedFile,
        trimStart,
        trimEnd,
        cropBox,
        displaySize,
        videoSize,
        exportFormat,
        onProgress: setProgress,
        onLog: (message) => {
          const parsed = parseFfmpegProgress(message);
          if (parsed !== null && clipDuration > 0) {
            setProgress(
              Math.min(99, Math.round((parsed / clipDuration) * 100))
            );
          }
        },
      });

      setOutputUrl(URL.createObjectURL(blob));
    } catch {
      setFfmpegError(t("processingError"));
    } finally {
      setIsProcessing(false);
    }
  }, [
    uploadedFile,
    ffmpegReady,
    displaySize,
    trimStart,
    trimEnd,
    cropBox,
    videoSize,
    exportFormat,
    outputUrl,
    t,
  ]);

  return (
    <div className="min-h-screen bg-gray-900 text-white">
      <header className="border-b border-gray-800 bg-gray-950">
        <div className="mx-auto flex max-w-5xl items-center gap-3 px-4 py-4">
          <Link
            href="/dashboard"
            className="flex items-center gap-1 rounded-md text-sm text-gray-400 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
          >
            <ArrowLeft className="h-4 w-4" aria-hidden />
            {t("back")}
          </Link>
          <Scissors className="h-5 w-5 text-blue-500" aria-hidden />
          <h1 className="font-heading text-lg font-semibold text-white">
            {t("title")}
          </h1>
        </div>
      </header>

      <main className="mx-auto max-w-5xl space-y-6 px-4 py-8">
        <TrimmerUploadZone
          uploadedFile={uploadedFile}
          onFileSelect={handleFileSelect}
        />

        {ffmpegError ? (
          <p className="rounded-lg border border-red-800 bg-red-950/50 px-4 py-3 text-sm text-red-300">
            {ffmpegError}
          </p>
        ) : null}

        {videoUrl ? (
          <>
            <TrimmerVideoPreview
              videoUrl={videoUrl}
              aspectRatio={aspectRatio}
              cropBox={cropBox}
              onCropChange={setCropBox}
              onAspectRatioChange={setAspectRatio}
              onVideoMetadata={handleVideoMetadata}
              onDisplaySize={setDisplaySize}
            />
            <TrimmerStrip
              videoUrl={videoUrl}
              duration={duration}
              trimStart={trimStart}
              trimEnd={trimEnd}
              onTrimChange={handleTrimChange}
            />
            <TrimmerExportSection
              exportFormat={exportFormat}
              onExportFormatChange={setExportFormat}
              isProcessing={isProcessing}
              progress={progress}
              ffmpegReady={ffmpegReady}
              hasVideo={Boolean(uploadedFile)}
              outputUrl={outputUrl}
              onProcess={handleProcess}
            />
          </>
        ) : null}
      </main>
    </div>
  );
}
