"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { get, post } from "@/lib/api";
import { Notice, Spinner } from "@/components/ui";
import { DataGrid, type ColDef } from "@/components/DataGrid";
import { StatusBadge } from "@/components/processingStatus";
import { InfoIcon } from "@/components/icons";
import { HistoryModal } from "@/components/panels/QueuePanel";
import { timeAgo } from "@/lib/format";

type Failed = {
  productId: string;
  sku: string | null;
  gtin: string | null;
  productName: string | null;
  variantName: string | null;
  status: string;
  runCount: number;
  finishedAt: string | null;
  score: number | null;
  costChf: number | null;
  message: string | null;
  targeted: boolean;
};

function TargetedCell(p: any) {
  return p.data?.targeted ? (
    <span className="badge bg-blue-100 text-brand" title="Targeted enrichment job">Targeted</span>
  ) : (
    <span className="text-slate-300">—</span>
  );
}

function InfoCell(p: any) {
  return (
    <button
      type="button"
      className="rounded-sm p-1 text-slate-400 hover:bg-slate-100 hover:text-brand"
      aria-label="Processing history"
      onClick={() => p.context.onInfo(p.data.productId)}
    >
      <InfoIcon className="h-4 w-4" />
    </button>
  );
}

// Stateful so the button can show its own in-flight state; the row leaves the list
// on the next refresh once the product is re-claimed.
function RetriggerCell(p: any) {
  const [busy, setBusy] = useState(false);
  return (
    <button
      type="button"
      className="btn-secondary px-2 py-1 text-xs"
      disabled={busy}
      title="Re-run this product through the full pipeline"
      onClick={async () => {
        setBusy(true);
        try {
          await p.context.onRetrigger(p.data.productId);
        } finally {
          setBusy(false);
        }
      }}
    >
      {busy ? "Re-queuing…" : "Retrigger"}
    </button>
  );
}

export default function FailedPanel() {
  const [items, setItems] = useState<Failed[] | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [updatedAt, setUpdatedAt] = useState<string | null>(null);
  const [historyId, setHistoryId] = useState<string | null>(null);
  const [msg, setMsg] = useState<string | null>(null);

  const load = useCallback(async () => {
    try {
      const d = await get<{ count: number; items: Failed[] }>("products/failed");
      setItems(d.items);
      setUpdatedAt(new Date().toISOString());
      setError(null);
    } catch (e) {
      setError((e as Error).message);
    }
  }, []);

  useEffect(() => {
    load();
    const t = setInterval(load, 8000); // refresh as products are retriggered / finish
    return () => clearInterval(t);
  }, [load]);

  const retrigger = useCallback(
    async (productId: string) => {
      setMsg(null);
      try {
        const r = await post<{ ok: boolean; claimed?: number; detail?: string; error?: string }>("queue/pickup", { productIds: [productId] });
        setMsg(r.ok ? r.detail || "Re-queued." : r.error || "Could not retrigger.");
      } catch (e) {
        setMsg((e as Error).message);
      }
      await load();
    },
    [load],
  );

  const columnDefs = useMemo<ColDef[]>(
    () => [
      { field: "sku", headerName: "SKU", flex: 1, minWidth: 140, valueFormatter: (p: any) => p.value || "—" },
      { headerName: "Product name", colId: "productName", flex: 1, minWidth: 160, valueGetter: (p: any) => p.data.productName || "—" },
      { headerName: "Job", colId: "targeted", width: 105, cellRenderer: TargetedCell, cellClass: "flex items-center", valueGetter: (p: any) => (p.data.targeted ? "Targeted" : "Full") },
      { field: "status", headerName: "Outcome", width: 130, cellRenderer: (p: any) => <StatusBadge status={String(p.value)} /> },
      { field: "message", headerName: "Reason", flex: 2, minWidth: 220, valueFormatter: (p: any) => p.value || "—", tooltipField: "message" },
      { field: "runCount", headerName: "Runs", width: 80 },
      { field: "finishedAt", headerName: "When", width: 160, valueFormatter: (p: any) => (p.value ? new Date(p.value).toLocaleString() : "—") },
      { headerName: "", colId: "retrigger", width: 130, sortable: false, filter: false, cellRenderer: RetriggerCell, cellClass: "flex items-center justify-center", pinned: "right" },
      { headerName: "", colId: "info", width: 56, sortable: false, filter: false, cellRenderer: InfoCell, cellClass: "flex items-center justify-center", pinned: "right" },
    ],
    [],
  );

  if (error) return <Notice kind="error">Could not load failed products: {error}</Notice>;
  if (!items) return <Spinner label="Loading failed products…" />;

  return (
    <>
      <p className="mb-3 text-sm text-slate-600">
        Products that did not complete cleanly — <strong>Failed</strong> (pipeline error) or <strong>Review</strong> (quality or
        write-back issue). Click the ⓘ for the full history; the <strong>Log</strong> tab shows the reason it failed.{" "}
        <strong>Retrigger</strong> re-runs the product through the full pipeline.
      </p>
      <div className="mb-3 flex flex-wrap items-center gap-3 text-xs text-slate-500" aria-live="polite">
        <span>{items.length} need attention · updated {timeAgo(updatedAt || undefined)}</span>
        {msg && <span className="text-sm text-slate-700" role="status">{msg}</span>}
      </div>

      {items.length === 0 ? (
        <Notice kind="success">No failed products — everything processed cleanly.</Notice>
      ) : (
        <DataGrid
          rowData={items}
          columnDefs={columnDefs}
          height={560}
          getRowId={(p: any) => String(p.data.productId)}
          context={{ onInfo: (id: string) => setHistoryId(id), onRetrigger: retrigger }}
        />
      )}

      <HistoryModal productId={historyId} onClose={() => setHistoryId(null)} />
    </>
  );
}
