/* Admin — AI configuration. Edit the model + prompt + knobs for each AI task
   without a code deploy, see per-model cost, and test against a sample matter.
   Assigns window.LedgerAdmin */
(function () {
  const fmtCost = (n) =>
    n == null ? "—" : "$" + Number(n).toLocaleString(undefined, { maximumFractionDigits: 6 });

  function TaskEditor({ task, models, onSaved }) {
    // Card/Button/Badge from the design system; form controls are native + app.css
    // styled (the DS Select takes an `options` array, which fights this grid layout).
    const { Card, Button, Badge } = window.LawCrimeDesignSystem_e18d68;
    const [model, setModel] = React.useState(task.model);
    const [prompt, setPrompt] = React.useState(task.prompt_template);
    const [maxTokens, setMaxTokens] = React.useState(task.max_tokens);
    const [temp, setTemp] = React.useState(task.temperature ?? 0);
    const [enabled, setEnabled] = React.useState(task.enabled);
    const [busy, setBusy] = React.useState(false);
    const [msg, setMsg] = React.useState(null);
    const [test, setTest] = React.useState(null);

    const dirty =
      model !== task.model || prompt !== task.prompt_template ||
      Number(maxTokens) !== task.max_tokens || Number(temp) !== Number(task.temperature ?? 0) ||
      enabled !== task.enabled;

    const chosen = models.find((m) => m.model === model);
    const tempIgnored = chosen && !chosen.supports_temperature;

    async function save() {
      setBusy(true); setMsg(null);
      try {
        await window.LedgerAPI.saveAiTask(task.task_key, {
          model, prompt_template: prompt, max_tokens: Number(maxTokens),
          temperature: Number(temp), enabled,
        });
        setMsg({ ok: true, text: "Saved. Takes effect on the next run — no deploy." });
        onSaved && onSaved();
      } catch (e) { setMsg({ ok: false, text: e.message || String(e) }); }
      finally { setBusy(false); }
    }

    async function runTest() {
      setBusy(true); setMsg(null); setTest(null);
      try {
        // Save first so the test uses exactly what's on screen, then dry-run.
        if (dirty) await save();
        const r = await window.LedgerAPI.testAiTask({
          working_title: "Idaho College Murders",
          editorial_notes:
            "Four University of Idaho students stabbed to death in Moscow, Idaho. " +
            "Suspect arrested weeks later. Death penalty on the table.",
        });
        setTest(r);
      } catch (e) { setMsg({ ok: false, text: e.message || String(e) }); }
      finally { setBusy(false); }
    }

    React.useEffect(() => { setTimeout(() => window.lucide && window.lucide.createIcons(), 20); });

    return (
      <Card style={{ marginBottom: 20 }}>
        <Card.Head title={task.display_name}>
          <Badge variant={enabled ? "live" : "neutral"}>{enabled ? "Enabled" : "Disabled"}</Badge>
        </Card.Head>
        <Card.Body>
          <p style={{ marginTop: 0, color: "var(--text-muted)", fontSize: 13 }}>{task.description}</p>

          <div className="ai-grid">
            <label className="ai-field">
              <span>Model</span>
              <select className="ai-input" value={model} onChange={(e) => setModel(e.target.value)}>
                {models.map((m) => (
                  <option key={m.model} value={m.model}>
                    {m.display_name} — ${m.input_cost_per_mtok}/${m.output_cost_per_mtok} per M tok
                  </option>
                ))}
              </select>
              {chosen && (
                <small className="ai-hint">
                  in ${chosen.input_cost_per_mtok} · out ${chosen.output_cost_per_mtok} per M tokens
                  {tempIgnored ? " · ignores temperature" : ""}
                </small>
              )}
            </label>

            <label className="ai-field">
              <span>Max tokens</span>
              <input className="ai-input" type="number" value={maxTokens} onChange={(e) => setMaxTokens(e.target.value)} />
            </label>

            <label className="ai-field">
              <span>Temperature{tempIgnored ? " (not used by this model)" : ""}</span>
              <input className="ai-input" type="number" step="0.1" min="0" max="1" value={temp}
                disabled={tempIgnored} onChange={(e) => setTemp(e.target.value)} />
            </label>

            <label className="ai-field">
              <span>Status</span>
              <select className="ai-input" value={enabled ? "on" : "off"} onChange={(e) => setEnabled(e.target.value === "on")}>
                <option value="on">Enabled</option>
                <option value="off">Disabled</option>
              </select>
            </label>
          </div>

          <label className="ai-field" style={{ marginTop: 14 }}>
            <span>Prompt template <small className="ai-hint">— placeholders: {"{{CASE_NAME}}"}, {"{{context}}"}. The controlled tag list is injected automatically from the taxonomy below.</small></span>
            <textarea className="ai-prompt" value={prompt} onChange={(e) => setPrompt(e.target.value)} rows={14} spellCheck={false} />
          </label>

          <div className="ai-actions">
            <Button variant="primary" icon="save" disabled={!dirty || busy} onClick={save}>Save</Button>
            <Button variant="ghost" icon="flask-conical" disabled={busy} onClick={runTest}>
              Test on sample matter
            </Button>
            {task.updated_at && (
              <span className="ai-hint" style={{ marginLeft: "auto" }}>
                updated {new Date(task.updated_at).toLocaleString()}
              </span>
            )}
          </div>

          {msg && (
            <div className={"ai-msg " + (msg.ok ? "ai-msg--ok" : "ai-msg--err")}>{msg.text}</div>
          )}

          {test && (
            <div className="ai-test">
              <div className="ai-test__head">
                <i data-lucide="flask-conical" />
                <b>Test result</b>
                <Badge variant="neutral">{test.model}</Badge>
                <span className="ai-hint">
                  {test.usage ? `${test.usage.input_tokens} in · ${test.usage.output_tokens} out` : ""} ·
                  est. {fmtCost(test.est_cost_usd)} / run
                </span>
              </div>
              <div className="ai-hint" style={{ margin: "4px 0 8px" }}>
                Would populate: {(test.would_update || []).join(", ") || "(nothing)"} — no matter was changed.
              </div>
              <pre className="ai-test__json">{JSON.stringify(test.extracted, null, 2)}</pre>
            </div>
          )}
        </Card.Body>
      </Card>
    );
  }

  function RunLog({ runs }) {
    const { Card } = window.LawCrimeDesignSystem_e18d68;
    return (
      <Card>
        <Card.Head title="Recent AI runs" />
        <Card.Body style={{ padding: 0 }}>
          {!runs ? (
            <div className="ai-empty">Loading…</div>
          ) : runs.length === 0 ? (
            <div className="ai-empty">No runs logged yet.</div>
          ) : (
            <table className="ai-runs">
              <thead>
                <tr><th>When</th><th>Task</th><th>Model</th><th>Tokens</th><th>Est. cost</th><th>Result</th></tr>
              </thead>
              <tbody>
                {runs.map((r) => (
                  <tr key={r.run_id}>
                    <td>{new Date(r.created_at).toLocaleString()}</td>
                    <td>{r.task_key}{r.is_test ? " (test)" : ""}</td>
                    <td>{r.model}</td>
                    <td>{r.input_tokens != null ? `${r.input_tokens}/${r.output_tokens}` : "—"}</td>
                    <td>{fmtCost(r.est_cost_usd)}</td>
                    <td>{r.success ? "✓" : "✗"}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </Card.Body>
      </Card>
    );
  }

  // One editable row in the tag taxonomy.
  function TagRow({ tag, onSaved }) {
    const [label, setLabel] = React.useState(tag.label);
    const [category, setCategory] = React.useState(tag.category || "");
    const [sort, setSort] = React.useState(tag.sort_order);
    const [enabled, setEnabled] = React.useState(tag.enabled);
    const [busy, setBusy] = React.useState(false);
    const dirty = label !== tag.label || category !== (tag.category || "") ||
      Number(sort) !== tag.sort_order || enabled !== tag.enabled;
    async function save(patch) {
      setBusy(true);
      try {
        await window.LedgerAPI.updateTag(tag.tag_key, patch || {
          label, category: category || null, sort_order: Number(sort), enabled,
        });
        onSaved && onSaved();
      } finally { setBusy(false); }
    }
    return (
      <tr className={enabled ? "" : "tagrow--off"}>
        <td className="tag-key">{tag.tag_key}</td>
        <td><input className="ai-input tag-in" value={label} onChange={(e) => setLabel(e.target.value)} /></td>
        <td><input className="ai-input tag-in" value={category} onChange={(e) => setCategory(e.target.value)} placeholder="—" /></td>
        <td><input className="ai-input tag-in tag-in--num" type="number" value={sort} onChange={(e) => setSort(e.target.value)} /></td>
        <td style={{ textAlign: "center" }}>
          <input type="checkbox" checked={enabled} disabled={busy}
            onChange={(e) => { setEnabled(e.target.checked); save({ enabled: e.target.checked }); }} />
        </td>
        <td style={{ textAlign: "right" }}>
          {dirty && <button type="button" className="link-btn" disabled={busy} onClick={() => save()}>Save</button>}
        </td>
      </tr>
    );
  }

  function TagManager() {
    const { Card, Button } = window.LawCrimeDesignSystem_e18d68;
    const [rows, setRows] = React.useState(null);
    const [adding, setAdding] = React.useState(false);
    const blank = { label: "", category: "", sort_order: "" };
    const [f, setF] = React.useState(blank);
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState(null);

    const load = React.useCallback(() => {
      window.LedgerAPI.listTags(false).then(setRows).catch((e) => setErr(e.message || String(e)));
    }, []);
    React.useEffect(() => { load(); }, [load]);
    React.useEffect(() => { setTimeout(() => window.lucide && window.lucide.createIcons(), 20); }, [rows, adding]);

    const slug = (s) => s.toLowerCase().trim().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
    async function add() {
      const key = slug(f.label);
      if (!key) { setErr("Enter a tag label."); return; }
      setBusy(true); setErr(null);
      try {
        const maxSort = (rows || []).reduce((mx, t) => Math.max(mx, t.sort_order || 0), 0);
        await window.LedgerAPI.createTag({
          tag_key: key, label: f.label.trim(), category: f.category || null,
          sort_order: f.sort_order === "" ? maxSort + 10 : Number(f.sort_order),
        });
        setF(blank); setAdding(false); load();
      } catch (e) { setErr(e.message || String(e)); }
      finally { setBusy(false); }
    }

    const enabledCount = (rows || []).filter((t) => t.enabled).length;

    return (
      <Card style={{ marginBottom: 20 }}>
        <Card.Head title="Tag taxonomy">
          <Button size="sm" variant="primary" icon="plus" onClick={() => setAdding((a) => !a)}>{adding ? "Close" : "Add tag"}</Button>
        </Card.Head>
        <Card.Body>
          <p style={{ marginTop: 0, color: "var(--text-muted)", fontSize: 13 }}>
            The single source of truth for matter tags. The AI enricher is restricted to the
            <b> enabled</b> tags below{rows ? ` (${enabledCount} of ${rows.length} enabled)` : ""} — disable a tag to keep
            it out of AI suggestions without deleting historical data.
          </p>

          {err && <div className="ai-msg ai-msg--err">{err}</div>}

          {adding && (
            <div className="ai-grid" style={{ marginBottom: 14 }}>
              <label className="ai-field"><span>Label</span>
                <input className="ai-input" value={f.label} onChange={(e) => setF((s) => ({ ...s, label: e.target.value }))} placeholder="e.g. Cold Case" />
                {f.label && <small className="ai-hint">key: {slug(f.label)}</small>}
              </label>
              <label className="ai-field"><span>Category</span>
                <input className="ai-input" value={f.category} onChange={(e) => setF((s) => ({ ...s, category: e.target.value }))} placeholder="crime / people / legal …" />
              </label>
              <label className="ai-field"><span>Sort order</span>
                <input className="ai-input" type="number" value={f.sort_order} onChange={(e) => setF((s) => ({ ...s, sort_order: e.target.value }))} placeholder="auto" />
              </label>
              <div className="ai-field" style={{ justifyContent: "flex-end" }}>
                <Button variant="primary" icon="check" disabled={busy} onClick={add}>{busy ? "Adding…" : "Add tag"}</Button>
              </div>
            </div>
          )}

          {rows === null ? <div className="ai-empty">Loading…</div> : (
            <table className="ai-runs tag-table">
              <thead><tr><th>Key</th><th>Label</th><th>Category</th><th>Sort</th><th>Enabled</th><th></th></tr></thead>
              <tbody>
                {rows.map((t) => <TagRow key={t.tag_key} tag={t} onSaved={load} />)}
              </tbody>
            </table>
          )}
        </Card.Body>
      </Card>
    );
  }

  function Admin() {
    const [tasks, setTasks] = React.useState(null);
    const [models, setModels] = React.useState([]);
    const [runs, setRuns] = React.useState(null);
    const [err, setErr] = React.useState(null);

    const load = React.useCallback(async () => {
      try {
        const [t, m, r] = await Promise.all([
          window.LedgerAPI.listAiTasks(),
          window.LedgerAPI.listAiModels(),
          window.LedgerAPI.listAiRuns(15),
        ]);
        setTasks(t); setModels(m); setRuns(r);
      } catch (e) { setErr(e.message || String(e)); }
    }, []);

    React.useEffect(() => { load(); }, [load]);

    return (
      <div>
        <div className="page-head">
          <div>
            <div className="eyebrow">Administration · AI</div>
            <h1 className="page-title">AI Configuration</h1>
          </div>
        </div>
        <p style={{ color: "var(--text-muted)", fontSize: 13, maxWidth: 720, marginTop: -4 }}>
          Model and prompt for every AI workload are configured here — not in code. Pick the
          cheapest model that does the job, edit the prompt, and test before it goes live.
        </p>

        {err && <div className="login__err" style={{ margin: "12px 0" }}>Couldn’t load: {err}</div>}

        {tasks === null && !err && <div className="ai-empty">Loading…</div>}
        {tasks && tasks.map((t) => (
          <TaskEditor key={t.task_key} task={t} models={models} onSaved={load} />
        ))}

        <TagManager />

        <RunLog runs={runs} />
      </div>
    );
  }

  window.LedgerAdmin = Admin;
})();
