"use client";

import Link from "next/link";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { ArrowLeft, Zap, Power, Cpu, HardDrive, MemoryStick } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { useToast } from "@/components/ui/use-toast";
import { cn } from "@/lib/utils";

interface MachineRow {
  id: string;
  name: string;
  hostname: string;
  enabled: boolean;
  status: "ONLINE" | "OFFLINE" | "DISABLED";
  lastSeenAt: string | null;
  workerVersion: string | null;
  aeVersion: string | null;
  availability: { mode?: string } | null;
  renderNowUntil: string | null;
  latestHeartbeat: {
    createdAt: string;
    cpuPercent: number | null;
    memPercent: number | null;
    diskFreeGb: number | null;
  } | null;
  currentJob: {
    id: string;
    exportId: string | null;
    shotCode: string | null;
    versionString: string | null;
    progress: number;
    etaSeconds: number | null;
  } | null;
}

const STATUS_STYLES: Record<string, string> = {
  ONLINE: "bg-green-500/15 text-green-400 border-green-500/30",
  OFFLINE: "bg-zinc-500/15 text-zinc-400 border-zinc-500/30",
  DISABLED: "bg-red-500/15 text-red-400 border-red-500/30",
};

export function MachinesClient() {
  const { data: session } = useSession();
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const isAdmin = ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(session?.user?.role ?? "");

  const { data, isLoading } = useQuery({
    queryKey: ["pipeline-machines"],
    queryFn: async () => {
      const res = await fetch("/api/machines");
      if (!res.ok) throw new Error("Failed to load machines");
      return res.json() as Promise<{ machines: MachineRow[] }>;
    },
    refetchInterval: 10000,
  });

  async function patch(machineId: string, body: Record<string, unknown>, okMsg: string) {
    const res = await fetch(`/api/machines/${machineId}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    const resBody = await res.json().catch(() => ({}));
    if (!res.ok) {
      toast({ title: "Update failed", description: resBody.error ?? res.statusText, variant: "destructive" });
    } else {
      toast({ title: okMsg });
    }
    queryClient.invalidateQueries({ queryKey: ["pipeline-machines"] });
  }

  const machines = data?.machines ?? [];

  return (
    <div className="p-6 space-y-6">
      <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-2xl font-semibold text-white">Render Machines</h1>
          <p className="text-sm text-zinc-400 mt-1">
            Worker status, render windows and the Render Now override
          </p>
        </div>
      </div>

      {isLoading ? (
        <div className="text-zinc-500">Loading…</div>
      ) : machines.length === 0 ? (
        <div className="rounded-lg border border-zinc-800 bg-zinc-900/40 p-10 text-center text-zinc-500">
          No machines registered yet — install the RenderWorker service on a workstation and it will
          appear here after its first registration.
        </div>
      ) : (
        <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
          {machines.map((m) => {
            const renderNowActive = m.renderNowUntil && new Date(m.renderNowUntil) > new Date();
            return (
              <div key={m.id} className="rounded-lg border border-zinc-800 bg-zinc-900 p-4 space-y-3">
                <div className="flex items-center justify-between">
                  <div>
                    <div className="text-white font-medium">{m.name}</div>
                    <div className="text-xs text-zinc-500">{m.hostname}</div>
                  </div>
                  <span
                    className={cn("rounded-full border px-2 py-0.5 text-xs", STATUS_STYLES[m.status])}
                  >
                    {m.status}
                  </span>
                </div>

                <div className="text-xs text-zinc-500 space-y-0.5">
                  <div>Worker {m.workerVersion ?? "?"} · AE {m.aeVersion ?? "?"}</div>
                  <div>
                    Availability: {m.availability?.mode ?? "ALWAYS"}
                    {renderNowActive && (
                      <span className="text-amber-400">
                        {" "}· Render Now until {new Date(m.renderNowUntil!).toLocaleTimeString()}
                      </span>
                    )}
                  </div>
                  {m.lastSeenAt && <div>Last seen {new Date(m.lastSeenAt).toLocaleString()}</div>}
                </div>

                {m.latestHeartbeat && (
                  <div className="flex items-center gap-4 text-xs text-zinc-400">
                    <span className="flex items-center gap-1">
                      <Cpu className="h-3.5 w-3.5" />
                      {m.latestHeartbeat.cpuPercent != null ? `${Math.round(m.latestHeartbeat.cpuPercent)}%` : "—"}
                    </span>
                    <span className="flex items-center gap-1">
                      <MemoryStick className="h-3.5 w-3.5" />
                      {m.latestHeartbeat.memPercent != null ? `${Math.round(m.latestHeartbeat.memPercent)}%` : "—"}
                    </span>
                    <span className="flex items-center gap-1">
                      <HardDrive className="h-3.5 w-3.5" />
                      {m.latestHeartbeat.diskFreeGb != null ? `${Math.round(m.latestHeartbeat.diskFreeGb)} GB free` : "—"}
                    </span>
                  </div>
                )}

                {m.currentJob ? (
                  <div className="rounded bg-zinc-800/60 p-2.5 space-y-1.5">
                    <div className="text-xs text-zinc-300">
                      Rendering{" "}
                      {m.currentJob.exportId ? (
                        <Link
                          href={`/pipeline/exports/${m.currentJob.exportId}`}
                          className="text-amber-400 hover:underline"
                        >
                          {m.currentJob.shotCode} {m.currentJob.versionString}
                        </Link>
                      ) : (
                        "job"
                      )}
                    </div>
                    <Progress value={m.currentJob.progress * 100} className="h-1.5" />
                  </div>
                ) : (
                  <div className="text-xs text-zinc-600">Idle</div>
                )}

                <div className="flex items-center gap-2 pt-1">
                  <Button
                    variant="outline"
                    size="sm"
                    disabled={!m.enabled}
                    onClick={() =>
                      patch(
                        m.id,
                        { renderNowHours: renderNowActive ? 0 : 4 },
                        renderNowActive ? "Render Now cleared" : "Render Now active for 4 h"
                      )
                    }
                  >
                    <Zap className={cn("h-4 w-4 mr-1.5", renderNowActive ? "text-amber-400" : "")} />
                    {renderNowActive ? "Stop Render Now" : "Render Now (4 h)"}
                  </Button>
                  {isAdmin && (
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() =>
                        patch(m.id, { enabled: !m.enabled }, m.enabled ? "Machine disabled" : "Machine enabled")
                      }
                    >
                      <Power className={cn("h-4 w-4 mr-1.5", m.enabled ? "text-red-400" : "text-green-400")} />
                      {m.enabled ? "Disable" : "Enable"}
                    </Button>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
