"use client";

import { useState } from "react";
import useSWR from "swr";
import AppShell from "@/components/AppShell";
import { PageHeader } from "@/components/ui";
import { api, fetcher } from "@/lib/api";
import { useAuth } from "@/lib/auth";

type SkillSummary = {
  id: string;
  name: string;
  description: string;
  priority: number;
  rule_ids: string[];
  path_hint: string;
};

type SkillsListResponse = {
  skills: SkillSummary[];
  path_hint: string;
};

type SkillDetail = SkillSummary & {
  markdown: string;
  match: Record<string, unknown>;
};

export default function SkillsPage() {
  const { user } = useAuth();
  const isAdmin = user?.role === "admin";
  const { data: listData } = useSWR<SkillsListResponse>("/api/skills", fetcher);

  const [selectedId, setSelectedId] = useState<string | null>(null);

  const [markdown, setMarkdown] = useState<string | null>(null);
  const [previewTitle, setPreviewTitle] = useState("VoIP issue");
  const [previewIssue, setPreviewIssue] = useState("one-way audio on SIP calls from crew phones");
  const [previewRuleId, setPreviewRuleId] = useState("");
  const [preview, setPreview] = useState<{ matched: Record<string, unknown>[] } | null>(null);
  const [saving, setSaving] = useState(false);
  const [msg, setMsg] = useState<string | null>(null);
  const [msgKind, setMsgKind] = useState<"ok" | "err">("ok");

  const skills = listData?.skills ?? [];
  const activeId = selectedId ?? skills[0]?.id ?? null;

  const { data: skillData, mutate } = useSWR<SkillDetail>(
    activeId ? `/api/skills/${activeId}` : null,
    fetcher,
  );

  const content = markdown ?? skillData?.markdown ?? "";

  const selectSkill = (id: string) => {
    setSelectedId(id);
    setMarkdown(null);
    setMsg(null);
  };

  const save = async () => {
    if (!activeId) return;
    setSaving(true);
    setMsg(null);
    try {
      await api(`/api/skills/${activeId}`, {
        method: "PUT",
        body: JSON.stringify({ markdown: content }),
      });
      setMsgKind("ok");
      setMsg("Skill saved — next task run will use it.");
      setMarkdown(null);
      mutate();
    } catch (err: unknown) {
      setMsgKind("err");
      setMsg(err instanceof Error ? err.message : "Save failed");
    } finally {
      setSaving(false);
    }
  };

  const runPreview = async () => {
    setPreview(null);
    try {
      const body: Record<string, string> = {
        title: previewTitle,
        issue: previewIssue,
      };
      if (previewRuleId.trim()) body.matched_rule_id = previewRuleId.trim();
      const res = await api<{ matched: Record<string, unknown>[] }>("/api/skills/preview", {
        method: "POST",
        body: JSON.stringify(body),
      });
      setPreview(res);
    } catch (err: unknown) {
      setMsgKind("err");
      setMsg(err instanceof Error ? err.message : "Preview failed");
    }
  };

  return (
    <AppShell>
      <PageHeader
        title="Agent skills"
        subtitle="Procedural guides injected into triage and reasoning — complements troubleshooting rules"
      />

      <div className="mb-6 grid gap-4 lg:grid-cols-2">
        <div className="card">
          <h3 className="mb-2 text-sm font-semibold">Skill preview</h3>
          <p className="mb-3 text-xs text-muted">Test which skills match a task title + issue.</p>
          <input
            className="input mb-2 w-full"
            value={previewTitle}
            onChange={(e) => setPreviewTitle(e.target.value)}
            placeholder="Task title"
          />
          <textarea
            className="input mb-2 min-h-[80px] w-full"
            value={previewIssue}
            onChange={(e) => setPreviewIssue(e.target.value)}
            placeholder="Issue description"
          />
          <input
            className="input mb-2 w-full"
            value={previewRuleId}
            onChange={(e) => setPreviewRuleId(e.target.value)}
            placeholder="Optional matched rule id (e.g. one-way-audio)"
          />
          <button type="button" className="btn-secondary" onClick={runPreview}>
            Preview match
          </button>
          {preview?.matched && preview.matched.length > 0 && (
            <pre className="mt-3 overflow-x-auto rounded-lg bg-panel2 p-3 text-xs">
              {JSON.stringify(preview.matched, null, 2)}
            </pre>
          )}
          {preview && preview.matched.length === 0 && (
            <p className="mt-3 text-sm text-muted">No skills matched.</p>
          )}
        </div>

        <div className="card">
          <h3 className="mb-2 text-sm font-semibold">Defined skills</h3>
          <ul className="space-y-2 text-sm">
            {skills.map((s) => (
              <li key={s.id}>
                <button
                  type="button"
                  onClick={() => selectSkill(s.id)}
                  className={`flex w-full justify-between gap-2 border-b border-edge/50 py-2 text-left transition ${
                    activeId === s.id ? "text-accent2" : "hover:text-white"
                  }`}
                >
                  <span>{s.name}</span>
                  <span className="text-xs text-muted">priority {s.priority}</span>
                </button>
                {s.rule_ids.length > 0 && (
                  <p className="pb-2 text-[11px] text-muted">Rules: {s.rule_ids.join(", ")}</p>
                )}
              </li>
            ))}
          </ul>
          <p className="mt-3 text-xs text-muted">Directory: {listData?.path_hint}</p>
        </div>
      </div>

      {activeId && (
        <div className="card">
          <div className="mb-2 flex items-center justify-between">
            <h3 className="text-sm font-semibold">
              {skillData?.name ?? activeId}{" "}
              <span className="font-normal text-muted">({skillData?.path_hint})</span>
            </h3>
            {!isAdmin && <span className="text-xs text-muted">Read-only (admin can edit)</span>}
          </div>
          {skillData?.description && (
            <p className="mb-3 text-xs text-muted">{skillData.description}</p>
          )}
          <textarea
            className="input min-h-[420px] w-full font-mono text-xs leading-relaxed"
            value={content}
            onChange={(e) => isAdmin && setMarkdown(e.target.value)}
            readOnly={!isAdmin}
            spellCheck={false}
          />
          {msg && (
            <p className={`mt-2 text-sm ${msgKind === "ok" ? "text-good" : "text-bad"}`}>{msg}</p>
          )}
          {isAdmin && (
            <button type="button" className="btn-primary mt-4" disabled={saving} onClick={save}>
              {saving ? "Saving…" : "Save skill"}
            </button>
          )}
        </div>
      )}
    </AppShell>
  );
}
