"use client";

/**
 * מתאמי-סוכנים (Adapter) — /operations panel.
 *
 * Migrate any committee agent between run-engines (Claude / Gemini / DeepSeek / Codex)
 * in BOTH companies at once, with a preflight that prevents the silent crash
 * (frontmatter `---` breaks the gemini/deepseek CLI; model must match provider;
 * gemini excludeTools is global). Built to the Claude Design mockup
 * `02d-operations-adapters.html`. The actual migration runs host-side
 * (scripts/migrate_agent_adapter.py) via the court-fetch bridge — see
 * useMigrateAdapter / POST /api/operations/agents/migrate-adapter.
 */

import { useState } from "react";
import { toast } from "sonner";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  usePaperclipAgents,
  type AgentPair,
} from "@/lib/api/paperclip-agents";
import {
  useMigrateAdapter,
  type MigrateAdapterRequest,
  type MigrateAdapterResult,
} from "@/lib/api/operations";

const ADAPTERS = [
  { value: "claude_local", label: "Claude", cls: "bg-info-bg text-info border-info/40" },
  { value: "gemini_local", label: "Gemini", cls: "bg-warn-bg text-warn border-warn/40" },
  { value: "deepseek_local", label: "DeepSeek", cls: "bg-gold-wash text-gold-deep border-gold/40" },
  { value: "codex_local", label: "Codex", cls: "bg-success-bg text-success border-success/40" },
] as const;

// Bilingual role subtitle under the agent name (mockup 02d) — display-only,
// keyed by the agent's Hebrew name. Falls back to none for unmapped agents.
const ROLE_SUBTITLE: Record<string, string> = {
  "עוזר משפטי": "CEO · מתזמר",
  "מנתח משפטי": "analyst",
  "כותב החלטה": "writer",
  "מנהל ידע": "אוצֵר-הלכות",
  "בודק איכות": "qa",
  "הגהת מסמכים": "proofreader",
  "שטן מליץ": "red-team (Gemini)",
};

function adapterCls(a: string | null | undefined): string {
  return ADAPTERS.find((x) => x.value === a)?.cls ?? "bg-rule-soft text-ink-muted border-rule";
}
function adapterLabel(a: string | null | undefined): string {
  return ADAPTERS.find((x) => x.value === a)?.label ?? a ?? "—";
}

/** A pending confirmation: the apply/revert to run, plus its preflight result. */
type PendingDialog = {
  title: string;
  body: MigrateAdapterRequest; // action is "apply" or "revert"
  preflight: MigrateAdapterResult | null;
  loadingPreflight: boolean;
  relax: boolean;
  showRelax: boolean;
};

export function AgentAdaptersPanel() {
  const { data, isLoading } = usePaperclipAgents();
  const migrate = useMigrateAdapter();
  const [targets, setTargets] = useState<Record<string, string>>({});
  const [dlg, setDlg] = useState<PendingDialog | null>(null);
  const busy = migrate.isPending;

  const currentOf = (p: AgentPair) =>
    p.master?.adapter_type ?? p.mirror?.adapter_type ?? null;
  const modelOf = (p: AgentPair) => p.master?.model ?? p.mirror?.model ?? "";
  const isAsymmetric = (p: AgentPair) =>
    !!p.master && !!p.mirror && p.master.adapter_type !== p.mirror.adapter_type;
  const targetFor = (p: AgentPair) => targets[p.name] ?? currentOf(p) ?? "claude_local";

  // Run a preflight (check) and open the confirm dialog pre-loaded with its output.
  async function openMigrate(agent: string, to: string, title: string) {
    setDlg({ title, body: { action: "apply", agent, to, relax_tools: true },
      preflight: null, loadingPreflight: true, relax: true, showRelax: false });
    try {
      const res = await migrate.mutateAsync({ action: "check", agent, to });
      const conflict = /excludeTools|כלי-כתיבה/.test(res.stdout);
      setDlg((d) => d && { ...d, preflight: res, loadingPreflight: false,
        showRelax: conflict, relax: conflict });
    } catch (e) {
      setDlg((d) => d && { ...d, loadingPreflight: false,
        preflight: { ok: false, exit_code: -1, stdout: "", stderr: String(e) } });
    }
  }

  function openRevert(agent: string, title: string) {
    setDlg({ title, body: { action: "revert", agent }, preflight: null,
      loadingPreflight: false, relax: false, showRelax: false });
  }

  // Confirm → run the dialog's apply/revert and toast on the script's exit code.
  async function confirmDialog() {
    if (!dlg) return;
    const body = { ...dlg.body, relax_tools: dlg.relax };
    try {
      const res = await migrate.mutateAsync(body);
      if (res.exit_code === 0) {
        toast.success(dlg.body.action === "revert" ? "הוחזר ל-Claude" : "המעבר הושלם בשתי החברות");
      } else {
        toast.error("הפעולה נכשלה — ראה פלט");
        // keep dialog open so the operator sees the failure output
        setDlg((d) => d && { ...d, preflight: res, loadingPreflight: false });
        return;
      }
    } catch (e) {
      toast.error(`שגיאה: ${String(e)}`);
      return;
    }
    setDlg(null);
  }

  const preflightBlocked = !!dlg?.preflight && dlg.body.action === "apply" && dlg.preflight.exit_code !== 0;

  return (
    <Card className="bg-surface border-rule shadow-sm">
      <CardContent className="px-6 py-5">
        <p className="text-ink-muted text-xs mb-4">
          העברת כל סוכן בין מנועי-ההרצה (Claude · Gemini · DeepSeek · Codex), בשתי החברות יחד. כל מעבר
          עובר preflight שמונע קריסה. מעבר ל-Gemini/DeepSeek = fallback מופחת-איכות — להחזיר ל-Claude
          כשטוקני-Claude חוזרים.
        </p>

        {/* Emergency fallback bar */}
        <div className="rounded-md border border-gold/40 bg-gold-wash px-4 py-3 mb-4 flex items-center gap-4 flex-wrap">
          <div className="min-w-0">
            <div className="text-[0.85rem] text-navy font-semibold">מצב-חירום · טוקני-Claude</div>
            <div className="text-[0.7rem] text-ink-muted">
              כשנגמרים הטוקנים — להפיל את כל הצוות ל-Gemini או ל-Codex בלחיצה, ולהחזיר כשחוזרים.
            </div>
          </div>
          <div className="flex items-center gap-2 ms-auto shrink-0">
            <Button size="sm" variant="outline" disabled={busy}
              onClick={() => openRevert("all", "החזרת כל הסוכנים ל-Claude (מצב-מקור)")}>
              החזר הכל ל-Claude
            </Button>
            <Button size="sm" variant="default" disabled={busy}
              onClick={() => openMigrate("all", "gemini_local", "העברת כל הסוכנים ל-Gemini ⚡")}>
              העבר הכל ל-Gemini ⚡
            </Button>
            <Button size="sm" variant="default" disabled={busy}
              className="bg-success text-white hover:bg-success/90"
              onClick={() => openMigrate("all", "codex_local", "העברת כל הסוכנים ל-Codex (gpt-5.5) ⚡")}>
              העבר הכל ל-Codex ⚡
            </Button>
          </div>
        </div>

        {isLoading || !data ? (
          <Skeleton className="h-40 w-full" />
        ) : (
          <div className="overflow-x-auto rounded-md border border-rule-soft">
            <Table>
              <TableHeader>
                <TableRow className="bg-parchment hover:bg-parchment border-rule">
                  <TableHead className="text-start text-[0.72rem] font-medium text-ink-muted">תפקיד</TableHead>
                  <TableHead className="text-start text-[0.72rem] font-medium text-ink-muted">מתאם נוכחי</TableHead>
                  <TableHead className="text-start text-[0.72rem] font-medium text-ink-muted">מודל</TableHead>
                  <TableHead className="text-start text-[0.72rem] font-medium text-ink-muted">העבר ל־</TableHead>
                  <TableHead className="text-start text-[0.72rem] font-medium text-ink-muted" aria-label="פעולה" />
                  <TableHead className="text-start text-[0.72rem] font-medium text-ink-muted">מצב</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.pairs.map((p) => {
                  const cur = currentOf(p);
                  const tgt = targetFor(p);
                  const migrated = cur !== "claude_local" && cur !== null;
                  const asym = isAsymmetric(p);
                  const subtitle = ROLE_SUBTITLE[p.name];
                  return (
                    <TableRow key={p.name} className={`border-rule-soft ${asym ? "bg-danger-bg/25" : ""}`}>
                      <TableCell className="py-2.5 align-middle">
                        <div className="text-[0.85rem] text-navy font-semibold leading-tight">{p.name}</div>
                        {subtitle ? (
                          <div className="text-[0.68rem] text-ink-muted leading-tight">{subtitle}</div>
                        ) : null}
                      </TableCell>
                      <TableCell className="py-2.5 align-middle">
                        <Badge variant="outline" className={`font-normal ${adapterCls(cur)}`}>
                          {adapterLabel(cur)}
                        </Badge>
                      </TableCell>
                      <TableCell className="py-2.5 align-middle">
                        <span className="text-[0.68rem] text-ink-soft font-mono" dir="ltr">
                          {modelOf(p) || "(default)"}
                        </span>
                      </TableCell>
                      <TableCell className="py-2.5 align-middle">
                        <Select value={tgt} onValueChange={(v) => setTargets((t) => ({ ...t, [p.name]: v }))}>
                          <SelectTrigger size="sm" className="w-[8.5rem]">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            {ADAPTERS.map((a) => (
                              <SelectItem key={a.value} value={a.value}>{a.label}</SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </TableCell>
                      <TableCell className="py-2.5 align-middle">
                        <div className="flex items-center gap-1.5">
                          <Button size="xs" variant="default" disabled={busy || tgt === cur}
                            onClick={() => openMigrate(p.name, tgt, `העברת "${p.name}" → ${adapterLabel(tgt)}`)}>
                            העבר
                          </Button>
                          {migrated ? (
                            <Button size="xs" variant="ghost" disabled={busy}
                              onClick={() => openRevert(p.name, `החזרת "${p.name}" למצב-מקור`)}>
                              החזר
                            </Button>
                          ) : null}
                        </div>
                      </TableCell>
                      <TableCell className="py-2.5 align-middle">
                        {asym ? (
                          <Badge variant="outline" className="font-normal bg-danger-bg text-danger border-danger/40 whitespace-nowrap">
                            ⚠ א-סימטרי
                          </Badge>
                        ) : migrated ? (
                          <Badge variant="outline" className="font-normal bg-warn-bg text-warn border-warn/40 whitespace-nowrap">
                            מועבר · fallback
                          </Badge>
                        ) : (
                          <Badge variant="outline" className="font-normal bg-success-bg text-success border-success/40">
                            תקין
                          </Badge>
                        )}
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </div>
        )}
      </CardContent>

      {/* Confirm dialog: preflight output + apply/revert */}
      <Dialog open={!!dlg} onOpenChange={(o) => !o && setDlg(null)}>
        <DialogContent className="max-w-xl">
          <DialogHeader>
            <DialogTitle>{dlg?.title}</DialogTitle>
            <DialogDescription>
              {dlg?.body.action === "revert"
                ? "שחזור מדויק למתאם ולמודל שהיו לפני המעבר, בשתי החברות."
                : "המעבר חל על שתי החברות (CMP + CMPA). Gemini/DeepSeek/Codex = fallback מופחת-איכות."}
            </DialogDescription>
          </DialogHeader>

          {dlg?.body.action === "apply" ? (
            <div className="space-y-3">
              <div className="text-[0.72rem] text-ink-muted">preflight:</div>
              {dlg.loadingPreflight ? (
                <Skeleton className="h-24 w-full" />
              ) : (
                <pre dir="ltr"
                  className={`text-[0.7rem] font-mono whitespace-pre-wrap max-h-56 overflow-auto rounded-md border p-2 ${
                    preflightBlocked ? "border-danger/40 bg-danger-bg" : "border-rule-soft bg-parchment"
                  }`}>
                  {(dlg.preflight?.stdout || "") + (dlg.preflight?.stderr || "") || "—"}
                </pre>
              )}
              {dlg.showRelax ? (
                <div className="flex items-center gap-2">
                  <Switch id="relax" checked={dlg.relax}
                    onCheckedChange={(c) => setDlg((d) => d && { ...d, relax: c })} />
                  <Label htmlFor="relax" className="text-[0.75rem] text-ink-soft">
                    שחרר כלי-כתיבה חסומים (excludeTools גלובלי לכל סוכני-Gemini)
                  </Label>
                </div>
              ) : null}
            </div>
          ) : null}

          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setDlg(null)} disabled={busy}>
              ביטול
            </Button>
            <Button size="sm" disabled={busy || dlg?.loadingPreflight || preflightBlocked}
              onClick={confirmDialog}>
              {dlg?.body.action === "revert" ? "החזר" : preflightBlocked ? "preflight חוסם" : "אשר העברה"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
