"use client";

import { useState } from "react";
import Link from "next/link";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { RefreshCw, RotateCcw, XCircle, CheckCircle2, Server } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useToast } from "@/components/ui/use-toast";
import { cn } from "@/lib/utils";
import {
  EXPORT_STATUS_STYLES,
  FAILED_STATUSES,
  ACTIVE_STATUSES,
  statusLabel,
  formatEta,
} from "./status-colors";

interface QueueExport {
  id: string;
  shotCode: string;
  episode: string | null;
  projectName: string;
  projectCode: string;
  versionString: string;
  status: string;
  statusChangedAt: string;
  createdAt: string;
  outputDir: string;
  job: {
    id: string;
    attempt: number;
    status: string;
    progress: number;
    currentFrame: number | null;
    totalFrames: number | null;
    etaSeconds: number | null;
    priority: number;
    machineName: string | null;
    errorMessage: string | null;
  } | null;
}

interface Props {
  projects: { id: string; name: string; code: string }[];
}

export function PipelineQueueClient({ projects }: Props) {
  const { data: session } = useSession();
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const [projectId, setProjectId] = useState<string>("all");
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const isAdmin = ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(session?.user?.role ?? "");

  const { data, isLoading, refetch, isFetching } = useQuery({
    queryKey: ["pipeline-queue", projectId, statusFilter],
    queryFn: async () => {
      const params = new URLSearchParams({ limit: "200" });
      if (projectId !== "all") params.set("projectId", projectId);
      if (statusFilter !== "all") params.set("status", statusFilter);
      const res = await fetch(`/api/render/queue?${params}`);
      if (!res.ok) throw new Error("Failed to load queue");
      return res.json() as Promise<{ exports: QueueExport[]; pagination: { total: number } }>;
    },
    refetchInterval: 5000,
  });

  const exports = data?.exports ?? [];
  const counts = {
    queued: exports.filter((e) => e.status === "QUEUED").length,
    rendering: exports.filter((e) => e.status === "RENDERING").length,
    failed: exports.filter((e) => FAILED_STATUSES.includes(e.status)).length,
    readyForQc: exports.filter((e) => e.status === "READY_FOR_QC").length,
    readyForDelivery: exports.filter((e) => e.status === "READY_FOR_DELIVERY").length,
  };

  async function action(exportId: string, verb: "retry" | "cancel" | "mark-done") {
    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" });
    } else {
      toast({ title: `Export ${verb === "mark-done" ? "marked done" : verb === "retry" ? "requeued" : "cancelled"}` });
    }
    queryClient.invalidateQueries({ queryKey: ["pipeline-queue"] });
  }

  const cards: { label: string; value: number; className?: string }[] = [
    { label: "Queued", value: counts.queued },
    { label: "Rendering", value: counts.rendering, className: "text-blue-400" },
    { label: "Failed", value: counts.failed, className: "text-red-400" },
    { label: "Ready for QC", value: counts.readyForQc, className: "text-amber-400" },
    { label: "Ready for Delivery", value: counts.readyForDelivery, className: "text-green-400" },
  ];

  return (
    <div className="p-6 space-y-6">
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <div>
          <h1 className="text-2xl font-semibold text-white">Render Queue</h1>
          <p className="text-sm text-zinc-400 mt-1">
            Exports queued from the AE panel — live status, retries and history
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Link href="/pipeline/machines">
            <Button variant="outline" size="sm">
              <Server className="h-4 w-4 mr-2" />
              Machines
            </Button>
          </Link>
          <Button variant="outline" size="sm" onClick={() => refetch()} disabled={isFetching}>
            <RefreshCw className={cn("h-4 w-4", isFetching && "animate-spin")} />
          </Button>
        </div>
      </div>

      {/* Summary cards */}
      <div className="grid grid-cols-2 sm:grid-cols-5 gap-3">
        {cards.map((c) => (
          <div key={c.label} className="rounded-lg border border-zinc-800 bg-zinc-900 px-4 py-3">
            <div className={cn("text-2xl font-semibold text-white", c.className)}>{c.value}</div>
            <div className="text-xs text-zinc-400 mt-0.5">{c.label}</div>
          </div>
        ))}
      </div>

      {/* Filters */}
      <div className="flex items-center gap-3 flex-wrap">
        <Select value={projectId} onValueChange={setProjectId}>
          <SelectTrigger className="w-56">
            <SelectValue placeholder="All projects" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All projects</SelectItem>
            {projects.map((p) => (
              <SelectItem key={p.id} value={p.id}>
                {p.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        <Select value={statusFilter} onValueChange={setStatusFilter}>
          <SelectTrigger className="w-56">
            <SelectValue placeholder="All statuses" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All statuses</SelectItem>
            {Object.keys(EXPORT_STATUS_STYLES).map((s) => (
              <SelectItem key={s} value={s}>
                {statusLabel(s)}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {/* Table */}
      <div className="rounded-lg border border-zinc-800 overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-zinc-800 bg-zinc-900/60 text-left text-xs text-zinc-400">
              <th className="px-4 py-2.5 font-medium">Shot</th>
              <th className="px-4 py-2.5 font-medium">Version</th>
              <th className="px-4 py-2.5 font-medium">Status</th>
              <th className="px-4 py-2.5 font-medium w-48">Progress</th>
              <th className="px-4 py-2.5 font-medium">Machine</th>
              <th className="px-4 py-2.5 font-medium">Attempt</th>
              <th className="px-4 py-2.5 font-medium">Queued</th>
              <th className="px-4 py-2.5 font-medium text-right">Actions</th>
            </tr>
          </thead>
          <tbody>
            {isLoading ? (
              <tr>
                <td colSpan={8} className="px-4 py-10 text-center text-zinc-500">
                  Loading…
                </td>
              </tr>
            ) : exports.length === 0 ? (
              <tr>
                <td colSpan={8} className="px-4 py-10 text-center text-zinc-500">
                  No exports yet — queue one from the After Effects panel
                </td>
              </tr>
            ) : (
              exports.map((e) => (
                <tr key={e.id} className="border-b border-zinc-800/60 hover:bg-zinc-900/40">
                  <td className="px-4 py-2.5">
                    <Link href={`/pipeline/exports/${e.id}`} className="text-white hover:text-amber-400 font-medium">
                      {e.shotCode}
                    </Link>
                    <div className="text-xs text-zinc-500">
                      {e.projectCode}
                      {e.episode ? ` · ep ${e.episode}` : ""}
                    </div>
                  </td>
                  <td className="px-4 py-2.5 text-zinc-300">{e.versionString}</td>
                  <td className="px-4 py-2.5">
                    <span
                      className={cn(
                        "inline-block rounded-full border px-2 py-0.5 text-xs whitespace-nowrap",
                        EXPORT_STATUS_STYLES[e.status] ?? "bg-zinc-500/15 text-zinc-300 border-zinc-500/30"
                      )}
                      title={e.job?.errorMessage ?? undefined}
                    >
                      {statusLabel(e.status)}
                    </span>
                  </td>
                  <td className="px-4 py-2.5">
                    {e.status === "RENDERING" && e.job ? (
                      <div className="space-y-1">
                        <Progress value={e.job.progress * 100} className="h-1.5" />
                        <div className="text-xs text-zinc-500">
                          {e.job.currentFrame != null && e.job.totalFrames != null
                            ? `frame ${e.job.currentFrame}/${e.job.totalFrames} · `
                            : ""}
                          ETA {formatEta(e.job.etaSeconds)}
                        </div>
                      </div>
                    ) : (
                      <span className="text-zinc-600 text-xs">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2.5 text-zinc-400">{e.job?.machineName ?? "—"}</td>
                  <td className="px-4 py-2.5 text-zinc-400">
                    {e.job ? `${e.job.attempt}` : "—"}
                  </td>
                  <td className="px-4 py-2.5 text-zinc-500 text-xs whitespace-nowrap">
                    {new Date(e.createdAt).toLocaleString()}
                  </td>
                  <td className="px-4 py-2.5">
                    <div className="flex items-center justify-end gap-1">
                      {FAILED_STATUSES.includes(e.status) && (
                        <Button variant="ghost" size="icon-sm" title="Retry" onClick={() => action(e.id, "retry")}>
                          <RotateCcw className="h-4 w-4 text-amber-400" />
                        </Button>
                      )}
                      {ACTIVE_STATUSES.includes(e.status) && (
                        <Button variant="ghost" size="icon-sm" title="Cancel" onClick={() => action(e.id, "cancel")}>
                          <XCircle className="h-4 w-4 text-red-400" />
                        </Button>
                      )}
                      {isAdmin && ["QUEUED", "RENDERING"].includes(e.status) && (
                        <Button
                          variant="ghost"
                          size="icon-sm"
                          title="Mark done manually (rendered outside the pipeline)"
                          onClick={() => action(e.id, "mark-done")}
                        >
                          <CheckCircle2 className="h-4 w-4 text-green-400" />
                        </Button>
                      )}
                    </div>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
