"use client";

import Link from "next/link";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { ArrowLeft, RotateCcw, XCircle } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast";
import { cn } from "@/lib/utils";
import {
  EXPORT_STATUS_STYLES,
  FAILED_STATUSES,
  ACTIVE_STATUSES,
  statusLabel,
} from "../../status-colors";

interface ExportDetail {
  export: {
    id: string;
    status: string;
    versionString: string;
    statusChangedAt: string;
    createdAt: string;
    aepPath: string;
    compName: string;
    outputDir: string;
    outputPattern: string;
    frameStart: number;
    frameEnd: number;
    fps: number;
    width: number;
    height: number;
    colorspace: string | null;
    exrFileCount: number | null;
    exrTotalBytes: number | null;
    vfxScope: string | null;
    submissionNote: string | null;
    submittedByName: string | null;
    shot: {
      id: string;
      shotCode: string;
      episode: string | null;
      project: { id: string; name: string; code: string };
    };
    renderJobs: {
      id: string;
      attempt: number;
      status: string;
      priority: number;
      progress: number;
      currentFrame: number | null;
      totalFrames: number | null;
      errorMessage: string | null;
      logTail: string | null;
      exitCode: number | null;
      claimedAt: string | null;
      startedAt: string | null;
      finishedAt: string | null;
      machine: { id: string; name: string } | null;
    }[];
    events: {
      id: string;
      fromStatus: string | null;
      toStatus: string;
      actorType: string;
      actorId: string | null;
      note: string | null;
      createdAt: string;
    }[];
  };
}

export function ExportDetailClient({ exportId }: { exportId: string }) {
  const { toast } = useToast();
  const queryClient = useQueryClient();

  const { data, isLoading, error } = useQuery({
    queryKey: ["pipeline-export", exportId],
    queryFn: async () => {
      const res = await fetch(`/api/render/exports/${exportId}`);
      if (!res.ok) throw new Error((await res.json().catch(() => ({})))?.error ?? "Failed to load export");
      return res.json() as Promise<ExportDetail>;
    },
    refetchInterval: 5000,
  });

  async function action(verb: "retry" | "cancel") {
    const res = await fetch(`/api/render/exports/${exportId}/${verb}`, { method: "POST" });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) {
      toast({ title: `${verb} failed`, description: body.error ?? res.statusText, variant: "destructive" });
    }
    queryClient.invalidateQueries({ queryKey: ["pipeline-export", exportId] });
  }

  if (isLoading) return <div className="p-6 text-zinc-500">Loading…</div>;
  if (error || !data) {
    return (
      <div className="p-6 text-red-400">
        {(error as Error)?.message ?? "Export not found"}
      </div>
    );
  }

  const e = data.export;
  const manifestRows: [string, string][] = [
    ["Project", `${e.shot.project.name} (${e.shot.project.code})`],
    ["Shot", e.shot.shotCode],
    ["Comp", e.compName],
    ["AEP", e.aepPath],
    ["Output dir", e.outputDir],
    ["Pattern", e.outputPattern],
    ["Frames", `${e.frameStart}–${e.frameEnd} @ ${e.fps} fps`],
    ["Resolution", `${e.width}×${e.height}`],
    ["Colorspace", e.colorspace ?? "—"],
    ["EXR files", e.exrFileCount != null ? String(e.exrFileCount) : "—"],
    ["Submitted by", e.submittedByName ?? "—"],
  ];

  return (
    <div className="p-6 space-y-6 max-w-5xl">
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <div className="flex items-center gap-3">
          <Link href="/pipeline">
            <Button variant="ghost" size="icon-sm">
              <ArrowLeft className="h-4 w-4" />
            </Button>
          </Link>
          <div>
            <h1 className="text-xl font-semibold text-white">
              {e.shot.shotCode} · {e.versionString}
            </h1>
            <span
              className={cn(
                "inline-block mt-1 rounded-full border px-2 py-0.5 text-xs",
                EXPORT_STATUS_STYLES[e.status] ?? ""
              )}
            >
              {statusLabel(e.status)}
            </span>
          </div>
        </div>
        <div className="flex items-center gap-2">
          {FAILED_STATUSES.includes(e.status) && (
            <Button variant="outline" size="sm" onClick={() => action("retry")}>
              <RotateCcw className="h-4 w-4 mr-2 text-amber-400" /> Retry
            </Button>
          )}
          {ACTIVE_STATUSES.includes(e.status) && (
            <Button variant="outline" size="sm" onClick={() => action("cancel")}>
              <XCircle className="h-4 w-4 mr-2 text-red-400" /> Cancel
            </Button>
          )}
        </div>
      </div>

      {/* Manifest */}
      <div className="rounded-lg border border-zinc-800 bg-zinc-900/40">
        <div className="px-4 py-2.5 border-b border-zinc-800 text-sm font-medium text-white">Manifest</div>
        <dl className="grid sm:grid-cols-2 gap-x-8 gap-y-2 p-4 text-sm">
          {manifestRows.map(([k, v]) => (
            <div key={k} className="flex gap-3">
              <dt className="w-28 shrink-0 text-zinc-500">{k}</dt>
              <dd className="text-zinc-300 break-all">{v}</dd>
            </div>
          ))}
        </dl>
      </div>

      {/* Per-submission slate fields */}
      {(e.vfxScope || e.submissionNote) && (
        <div className="rounded-lg border border-zinc-800 bg-zinc-900/40">
          <div className="px-4 py-2.5 border-b border-zinc-800 text-sm font-medium text-white">
            Submission
          </div>
          <dl className="p-4 space-y-3 text-sm">
            {e.vfxScope && (
              <div>
                <dt className="text-zinc-500 mb-0.5">VFX Scope</dt>
                <dd className="text-zinc-300 whitespace-pre-wrap">{e.vfxScope}</dd>
              </div>
            )}
            {e.submissionNote && (
              <div>
                <dt className="text-zinc-500 mb-0.5">Submission Note</dt>
                <dd className="text-zinc-300 whitespace-pre-wrap">{e.submissionNote}</dd>
              </div>
            )}
          </dl>
        </div>
      )}

      {/* Render attempts */}
      <div className="rounded-lg border border-zinc-800 bg-zinc-900/40">
        <div className="px-4 py-2.5 border-b border-zinc-800 text-sm font-medium text-white">
          Render attempts
        </div>
        <div className="divide-y divide-zinc-800/60">
          {e.renderJobs.map((j) => (
            <div key={j.id} className="p-4 text-sm">
              <div className="flex items-center gap-3 flex-wrap">
                <span className="text-white font-medium">Attempt {j.attempt}</span>
                <span className="text-xs text-zinc-400">{j.status}</span>
                <span className="text-xs text-zinc-500">{j.machine?.name ?? "unclaimed"}</span>
                {j.exitCode != null && <span className="text-xs text-zinc-500">exit {j.exitCode}</span>}
                {j.startedAt && (
                  <span className="text-xs text-zinc-500">
                    started {new Date(j.startedAt).toLocaleString()}
                  </span>
                )}
                {j.finishedAt && (
                  <span className="text-xs text-zinc-500">
                    finished {new Date(j.finishedAt).toLocaleString()}
                  </span>
                )}
              </div>
              {j.errorMessage && <div className="mt-1 text-xs text-red-400">{j.errorMessage}</div>}
              {j.logTail && (
                <details className="mt-2">
                  <summary className="text-xs text-zinc-500 cursor-pointer hover:text-zinc-300">
                    Log tail
                  </summary>
                  <pre className="mt-2 max-h-64 overflow-auto rounded bg-black/40 p-3 text-xs text-zinc-400 whitespace-pre-wrap">
                    {j.logTail}
                  </pre>
                </details>
              )}
            </div>
          ))}
          {e.renderJobs.length === 0 && (
            <div className="p-4 text-sm text-zinc-500">No attempts yet</div>
          )}
        </div>
      </div>

      {/* Event timeline */}
      <div className="rounded-lg border border-zinc-800 bg-zinc-900/40">
        <div className="px-4 py-2.5 border-b border-zinc-800 text-sm font-medium text-white">Timeline</div>
        <ol className="p-4 space-y-2">
          {e.events.map((ev) => (
            <li key={ev.id} className="flex items-start gap-3 text-sm">
              <span className="text-xs text-zinc-500 w-40 shrink-0 whitespace-nowrap">
                {new Date(ev.createdAt).toLocaleString()}
              </span>
              <span className="text-zinc-300">
                {ev.fromStatus ? `${statusLabel(ev.fromStatus)} → ` : ""}
                {statusLabel(ev.toStatus)}
                <span className="text-zinc-500"> · {ev.actorType.toLowerCase()}</span>
                {ev.note && <span className="block text-xs text-zinc-500">{ev.note}</span>}
              </span>
            </li>
          ))}
        </ol>
      </div>
    </div>
  );
}
