"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import useSWR from "swr";
import AppShell from "@/components/AppShell";
import { EmptyState, LoadError, Modal, PageHeader, SkeletonRows, StatusBadge } from "@/components/ui";
import { useToast } from "@/components/toast";
import { api, fetcher } from "@/lib/api";
import { useAuth, roleAtLeast } from "@/lib/auth";

type Mcp = {
  name: string;
  status: string;
  error: string | null;
  source?: string;
  tools: { name: string; description: string | null }[];
};

export default function McpPage() {
  const router = useRouter();
  const { user } = useAuth();
  const isAdmin = roleAtLeast(user?.role, "admin");
  const toast = useToast();
  const {
    data: mcps,
    error: mcpError,
    isLoading,
    mutate,
  } = useSWR<Mcp[]>("/api/mcp/servers", fetcher, { refreshInterval: 15000 });
  const [expanded, setExpanded] = useState<string | null>(null);
  const [busy, setBusy] = useState<string | null>(null);
  const [developOpen, setDevelopOpen] = useState<string | null>(null);
  const [developIssue, setDevelopIssue] = useState("");

  const run = async (key: string, label: string, fn: () => Promise<void>) => {
    setBusy(key);
    try {
      await fn();
      toast.success(`${label} — status will refresh shortly.`);
      mutate();
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : "Action failed");
    } finally {
      setBusy(null);
    }
  };

  return (
    <AppShell>
      <PageHeader
        title="MCP Servers"
        subtitle="Device integrations — reload or upgrade when tools fail or repos change"
        action={
          isAdmin && (
            <button
              className="btn-ghost text-sm"
              disabled={!!busy}
              onClick={() =>
                run("all", "Reload all queued", async () => {
                  await api("/api/mcp/reload-all", { method: "POST" });
                })
              }
            >
              {busy === "all" ? "Reloading…" : "Reload all"}
            </button>
          )
        }
      />

      {isLoading && !mcps ? (
        <SkeletonRows rows={4} />
      ) : mcpError ? (
        <LoadError message="Couldn’t load MCP servers." onRetry={() => mutate()} />
      ) : (mcps || []).length === 0 ? (
        <EmptyState
          title="No MCP servers reported yet"
          description="The worker clones and launches them on startup; check worker logs if this persists."
        />
      ) : (
      <div className="space-y-4">
        {(mcps || []).map((m) => (
          <div key={m.name} className="card">
            <div className="flex w-full flex-wrap items-center justify-between gap-3">
              <button
                className="flex flex-1 items-center gap-3 text-left"
                onClick={() => setExpanded(expanded === m.name ? null : m.name)}
              >
                <span className="font-medium">{m.name}</span>
                <span className="text-xs text-muted">
                  {m.tools?.length || 0} tools · {m.source || "git"}
                </span>
              </button>
              <div className="flex items-center gap-2">
                {isAdmin && (
                  <>
                    <button
                      className="btn-ghost btn-sm"
                      disabled={!!busy}
                      onClick={() =>
                        run(`reload-${m.name}`, "Reload queued", async () => {
                          await api(`/api/mcp/servers/${m.name}/reload`, { method: "POST" });
                        })
                      }
                    >
                      {busy === `reload-${m.name}` ? "…" : "Reload"}
                    </button>
                    <button
                      className="btn-ghost btn-sm text-accent2"
                      disabled={!!busy}
                      onClick={() =>
                        run(`upgrade-${m.name}`, "Upgrade queued", async () => {
                          await api(`/api/mcp/servers/${m.name}/upgrade`, { method: "POST" });
                        })
                      }
                    >
                      {busy === `upgrade-${m.name}` ? "…" : "Upgrade"}
                    </button>
                    <button
                      className="btn-ghost btn-sm text-accent"
                      disabled={!!busy}
                      onClick={() => {
                        setDevelopIssue("");
                        setDevelopOpen(m.name);
                      }}
                    >
                      Develop
                    </button>
                  </>
                )}
                <StatusBadge status={m.status} />
              </div>
            </div>
            {m.error && <div className="mt-2 text-sm text-bad">{m.error}</div>}
            {expanded === m.name && m.tools?.length > 0 && (
              <div className="mt-4 grid grid-cols-1 gap-2 md:grid-cols-2">
                {m.tools.map((t) => (
                  <div key={t.name} className="rounded-lg bg-panel2 px-3 py-2">
                    <div className="font-mono text-xs text-accent2">{t.name}</div>
                    {t.description && (
                      <div className="mt-1 line-clamp-2 text-xs text-muted">{t.description}</div>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>
      )}

      <Modal
        open={!!developOpen}
        onClose={() => setDevelopOpen(null)}
        title={`Develop ${developOpen || ""}`}
      >
        <p className="text-sm text-muted">
          Describe the missing tool or bug. A monitor task opens automatically so you can watch
          analyze → patch → reload → git push in the task timeline. Push to Gitea needs approval
          unless auto-push is enabled.
        </p>
        <textarea
          className="input mt-4 min-h-[120px]"
          value={developIssue}
          onChange={(e) => setDevelopIssue(e.target.value)}
          placeholder="e.g. add pfsense_list_firewall_rules_by_interface or fix NameError in get_firewall_log"
        />
        <div className="mt-4 flex justify-end gap-2">
          <button className="btn-ghost" onClick={() => setDevelopOpen(null)}>
            Cancel
          </button>
          <button
            className="btn-primary"
            disabled={!developIssue.trim() || !!busy}
            onClick={() => {
              const server = developOpen;
              if (!server) return;
              run(`develop-${server}`, "Develop started", async () => {
                const res = await api<{ task_id?: number; summary?: string }>(
                  `/api/mcp/servers/${server}/develop`,
                  {
                    method: "POST",
                    body: JSON.stringify({ issue: developIssue.trim() }),
                  }
                );
                setDevelopOpen(null);
                if (res.task_id) {
                  router.push(`/tasks/${res.task_id}`);
                }
              });
            }}
          >
            {busy === `develop-${developOpen}` ? "Starting…" : "Run & monitor"}
          </button>
        </div>
      </Modal>
    </AppShell>
  );
}
