"use client";

import { useCallback, useEffect, useState } from "react";
import { useParams, useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import {
  ArrowLeft,
  CheckCircle2,
  Download,
  Link2,
  Loader2,
  RefreshCw,
} from "lucide-react";

import { apiFetch } from "@/lib/api/fetch";
import { RENDER_EXPORT_PRESETS, type RenderExportPreset } from "@/lib/render-presets";
import type { RenderSettings } from "@/lib/render-schemas";
import { cn } from "@/lib/utils";

type Phase = "config" | "submitting" | "polling" | "completed" | "failed";

interface StatusResponse {
  status: string;
  progress: number;
  outputUrl: string | null;
  progressMessage?: string | null;
  errorMessage?: string | null;
  previewB64?: string | null;
}

interface ActiveRender {
  id: string;
  saved_project_id: string;
  step: string;
  render_progress: number;
}

const RESOLUTIONS: RenderSettings["resolution"][] = ["720p", "1080p", "4K"];
const FPS_OPTIONS: RenderSettings["fps"][] = [24, 30, 60];

export default function RenderPage() {
  const router = useRouter();
  const params = useParams<{ projectId: string }>();
  const search = useSearchParams();
  const projectId = params.projectId;
  const presetKey = search.get("preset") as RenderExportPreset | null;

  const [resolution, setResolution] = useState<RenderSettings["resolution"]>("1080p");
  const [fps, setFps] = useState<RenderSettings["fps"]>(30);
  const [phase, setPhase] = useState<Phase>("config");
  const [jobId, setJobId] = useState<string | null>(null);
  const [progress, setProgress] = useState(0);
  const [progressMessage, setProgressMessage] = useState("");
  const [previewB64, setPreviewB64] = useState<string | null>(null);
  const [outputUrl, setOutputUrl] = useState<string | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  // An active render that belongs to a DIFFERENT project (blocks starting a new one).
  const [blockingJobId, setBlockingJobId] = useState<string | null>(null);

  // Apply preset from the query (?preset=full)
  useEffect(() => {
    if (!presetKey || !RENDER_EXPORT_PRESETS[presetKey]) return;
    const cfg = RENDER_EXPORT_PRESETS[presetKey];
    setResolution(cfg.settings.resolution);
    setFps(cfg.settings.fps);
  }, [presetKey]);

  // On mount: resume this project's render if one is in flight, or flag a render
  // running on another project so we can block starting a new one.
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await apiFetch("/api/render/active");
        const data = (await res.json()) as { active?: ActiveRender[] };
        if (cancelled) return;
        const mine = data.active?.find((a) => a.saved_project_id === projectId);
        if (mine) {
          setJobId(mine.id);
          setPhase("polling");
          setProgress(mine.render_progress ?? 0);
          return;
        }
        const other = data.active?.[0];
        if (other) setBlockingJobId(other.id);
      } catch {
        /* ignore — config view will show */
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [projectId]);

  // Poll status while rendering.
  useEffect(() => {
    if (phase !== "polling" || !jobId) return;

    const poll = async () => {
      try {
        const res = await apiFetch(`/api/render/${jobId}/status`);
        const data = (await res.json()) as StatusResponse;
        if (!res.ok) {
          setPhase("failed");
          setErrorMessage("Could not fetch render status.");
          return;
        }
        setProgress(data.progress ?? 0);
        setProgressMessage(data.progressMessage ?? `Rendering… ${data.progress}%`);
        if (data.previewB64) setPreviewB64(data.previewB64);

        if (data.status === "completed") {
          if (data.outputUrl) setOutputUrl(data.outputUrl);
          setProgress(100);
          setPhase("completed");
        } else if (data.status === "failed") {
          setPhase("failed");
          setErrorMessage(data.errorMessage ?? "Render failed.");
        }
      } catch {
        setPhase("failed");
        setErrorMessage("Network error while polling status.");
      }
    };

    poll();
    const id = window.setInterval(poll, 2500);
    return () => window.clearInterval(id);
  }, [phase, jobId]);

  const startRender = useCallback(async () => {
    setPhase("submitting");
    setErrorMessage(null);
    try {
      const res = await apiFetch("/api/render", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          projectId,
          settings: { resolution, format: "mp4" as const, fps },
        }),
      });
      const data = (await res.json()) as { jobId?: string; error?: string; code?: string };
      if (res.status === 409 || data.code === "active_render_limit") {
        setPhase("config");
        setErrorMessage(
          data.error ?? "You already have an active render. Wait for it to finish."
        );
        return;
      }
      if (!res.ok || !data.jobId) {
        setPhase("failed");
        setErrorMessage(data.error ?? "Failed to start render.");
        return;
      }
      setJobId(data.jobId);
      setProgress(0);
      setProgressMessage("Queued for rendering…");
      setPhase("polling");
    } catch {
      setPhase("failed");
      setErrorMessage("Could not reach the render service.");
    }
  }, [projectId, resolution, fps]);

  const backToStudio = `/studio/video/${projectId}`;
  const isBusy = phase === "submitting" || phase === "polling";

  return (
    <div className="flex min-h-screen flex-col bg-[#070811] text-gray-100">
      {/* Top bar */}
      <header className="flex h-14 shrink-0 items-center justify-between border-b border-[#1a1d2e] px-4">
        <Link
          href={backToStudio}
          className="flex items-center gap-2 text-sm text-gray-400 hover:text-white"
        >
          <ArrowLeft className="h-4 w-4" />
          بازگشت به استودیو
        </Link>
        <span className="text-sm font-medium text-gray-300">خروجی رندر</span>
        <span className="w-28" />
      </header>

      <main className="mx-auto flex w-full max-w-5xl flex-1 flex-col items-center justify-center gap-6 p-6">
        {/* Preview / hero */}
        <div className="relative aspect-video w-full max-w-3xl overflow-hidden rounded-2xl border border-[#1a1d2e] bg-[#0c0e1a]">
          {previewB64 ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={`data:image/png;base64,${previewB64}`}
              alt="Render preview"
              className="h-full w-full object-cover"
            />
          ) : (
            <div className="flex h-full w-full items-center justify-center">
              {isBusy ? (
                <Loader2 className="h-10 w-10 animate-spin text-primary-500/40" />
              ) : phase === "completed" ? (
                <CheckCircle2 className="h-12 w-12 text-emerald-400" />
              ) : (
                <span className="text-sm text-gray-600">پیش‌نمایش رندر اینجا نمایش داده می‌شود</span>
              )}
            </div>
          )}
          {isBusy && (
            <div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/80 to-transparent p-4">
              <div className="mb-1.5 flex justify-between text-xs text-gray-300">
                <span>{progressMessage || "در حال رندر…"}</span>
                <span>{progress}%</span>
              </div>
              <div className="h-2 overflow-hidden rounded-full bg-white/10">
                <div
                  className="h-full rounded-full bg-primary-500 transition-all duration-500"
                  style={{ width: `${progress}%` }}
                />
              </div>
            </div>
          )}
        </div>

        {/* State-specific panel */}
        {phase === "completed" ? (
          <div className="w-full max-w-md space-y-3 text-center">
            <p className="text-lg font-semibold text-emerald-400">ویدیوی شما آماده است!</p>
            <div className="flex flex-col gap-2">
              {outputUrl ? (
                <>
                  <a
                    href={outputUrl}
                    download
                    className="inline-flex items-center justify-center gap-2 rounded-lg bg-primary-600 px-4 py-3 text-sm font-medium text-white hover:bg-primary-700"
                  >
                    <Download className="h-4 w-4" />
                    دانلود MP4
                  </a>
                  <a
                    href={outputUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center justify-center gap-2 rounded-lg border border-[#2a2d3e] px-4 py-2.5 text-sm text-gray-200 hover:bg-[#161a2b]"
                  >
                    <Link2 className="h-4 w-4" />
                    لینک اشتراک‌گذاری
                  </a>
                </>
              ) : (
                <p className="rounded-lg border border-[#2a2d3e] bg-[#0c0e1a] px-3 py-2.5 text-xs text-gray-400">
                  رندر در محیط توسعه کامل شد (بدون فایل خروجی واقعی). در محیط تولید، لینک دانلود اینجا
                  نمایش داده می‌شود.
                </p>
              )}
              <Link
                href={backToStudio}
                className="mt-1 text-xs text-gray-500 hover:text-gray-300"
              >
                بازگشت به استودیو
              </Link>
            </div>
          </div>
        ) : phase === "failed" ? (
          <div className="w-full max-w-md space-y-3 text-center">
            <p className="rounded-lg border border-red-900/50 bg-red-950/40 px-4 py-3 text-sm text-red-300">
              {errorMessage ?? "خطایی رخ داد."}
            </p>
            <button
              type="button"
              onClick={startRender}
              className="inline-flex w-full items-center justify-center gap-2 rounded-lg bg-primary-600 px-4 py-2.5 text-sm font-medium text-white hover:bg-primary-700"
            >
              <RefreshCw className="h-4 w-4" />
              تلاش دوباره
            </button>
          </div>
        ) : isBusy ? (
          <p className="text-sm text-gray-400">
            می‌توانید این صفحه را ببندید؛ رندر در پس‌زمینه ادامه می‌یابد و از هر صفحه‌ای قابل پیگیری است.
          </p>
        ) : (
          // Config
          <div className="w-full max-w-md space-y-5">
            {errorMessage && (
              <p className="rounded-lg border border-amber-900/50 bg-amber-950/40 px-3 py-2 text-sm text-amber-300">
                {errorMessage}
              </p>
            )}
            {blockingJobId && (
              <div className="rounded-lg border border-amber-900/50 bg-amber-950/30 px-3 py-2.5 text-sm text-amber-200">
                شما یک رندر فعال دارید.{" "}
                <button
                  className="underline hover:text-white"
                  onClick={() => router.push(`/studio/render/${projectId}`)}
                >
                  ابتدا آن را کامل کنید.
                </button>
              </div>
            )}
            <div>
              <p className="mb-2 text-xs font-medium text-gray-400">کیفیت</p>
              <div className="flex gap-2">
                {RESOLUTIONS.map((item) => (
                  <button
                    key={item}
                    type="button"
                    onClick={() => setResolution(item)}
                    className={cn(
                      "flex-1 rounded-lg border py-2.5 text-sm font-medium",
                      resolution === item
                        ? "border-primary-500 bg-primary-600/20 text-white"
                        : "border-[#2a2d3e] text-[#8b91a7] hover:border-[#3d4260]"
                    )}
                  >
                    {item}
                  </button>
                ))}
              </div>
            </div>
            <div>
              <p className="mb-2 text-xs font-medium text-gray-400">نرخ فریم</p>
              <div className="flex gap-2">
                {FPS_OPTIONS.map((item) => (
                  <button
                    key={item}
                    type="button"
                    onClick={() => setFps(item)}
                    className={cn(
                      "flex-1 rounded-lg border py-2.5 text-sm font-medium",
                      fps === item
                        ? "border-primary-500 bg-primary-600/20 text-white"
                        : "border-[#2a2d3e] text-[#8b91a7] hover:border-[#3d4260]"
                    )}
                  >
                    {item} fps
                  </button>
                ))}
              </div>
            </div>
            <button
              type="button"
              onClick={startRender}
              disabled={!!blockingJobId}
              className="w-full rounded-lg bg-primary-600 px-4 py-3 text-sm font-semibold text-white hover:bg-primary-700 disabled:cursor-not-allowed disabled:opacity-50"
            >
              شروع رندر
            </button>
          </div>
        )}
      </main>
    </div>
  );
}
