// dashboard-config-editor-services-ai-gene.js — extracted verbatim from dashboard.js (pure move).

// ── Config editor — services + AI-generated filters ─────────────
async function renderIcpConfigEditor(body) {
  body.innerHTML = "";
  const cfg = icpState.config;

  // Lazy-load services + filters
  if (!icpState.services) {
    const s = await api("icp-services-get").catch(() => ({ services: [] }));
    icpState.services = Array.isArray(s?.services) ? s.services : [];
  }
  if (!icpState.filters) {
    const f = await api("icp-filters-get").catch(() => ({ filters: [] }));
    icpState.filters = Array.isArray(f?.filters) ? f.filters : [];
  }

  // ── Auto-configure from user's website ─────────────────────
  const autoBox = el(
    "div",
    {
      class: "wizard-section",
      style: "background:var(--accent-soft);border:1px solid var(--accent);",
    },
    [
      el("div", { class: "wizard-section-title" }, "🪄 Auto-configure from your website"),
      el(
        "div",
        { class: "muted small", style: "margin-bottom:12px;" },
        "Paste your product URL. Claude reads it, infers the services you sell, and proposes AI-generated filter criteria for ranking crypto targets. Review & save.",
      ),
    ],
  );
  const urlInput = el("input", {
    class: "wizard-input",
    type: "url",
    id: "icp-autocfg-url",
    placeholder: "https://your-crypto-product.xyz",
    style: "margin-bottom:8px;",
  });
  const statusLine = el("div", { class: "muted small", id: "icp-autocfg-status" });
  const runBtn = el(
    "button",
    {
      class: "btn btn-primary",
      type: "button",
      onclick: async () => {
        const url = urlInput.value.trim();
        if (!url) {
          toast("Enter a URL first", "err");
          return;
        }
        runBtn.textContent = "Analyzing (15–30s)…";
        runBtn.disabled = true;
        statusLine.textContent = "Fetching website and asking Claude (fetch + services + filters)…";
        try {
          const r = await api("icp-auto-config", { body: { websiteUrl: url } });
          if (r?.error) {
            toast(`❌ ${r.error}`, "err");
            statusLine.textContent = r.error;
          } else {
            icpState.config = r.config;
            icpState._autoSummary = r.summary || "";
            if (Array.isArray(r.services)) icpState.services = r.services;
            if (Array.isArray(r.filters)) icpState.filters = r.filters;
            toast(
              `✅ Proposed ${r.services?.length || 0} services + ${r.filters?.length || 0} filters — review & save`,
              "ok",
            );
            statusLine.textContent = `✓ ${r.summary || "Config updated"} (analyzed ${r.chars_analyzed} chars)`;
            renderIcp();
            return;
          }
        } catch (err) {
          toast(`❌ ${err.message}`, "err");
          statusLine.textContent = err.message;
        }
        runBtn.textContent = "Analyze website → propose services + filters";
        runBtn.disabled = false;
      },
    },
    "Analyze website → propose services + filters",
  );
  autoBox.appendChild(urlInput);
  autoBox.appendChild(runBtn);
  autoBox.appendChild(statusLine);
  if (icpState._autoSummary) {
    autoBox.appendChild(
      el(
        "div",
        { class: "muted small", style: "margin-top:8px;font-style:italic;" },
        `Last AI summary: ${icpState._autoSummary}`,
      ),
    );
  }
  body.appendChild(autoBox);

  // ── Services panel ─────────────────────────────────────────
  body.appendChild(renderIcpServicesPanel());

  // ── Filters panel ─────────────────────────────────────────
  body.appendChild(renderIcpFiltersPanel());

  // ── Save bar ──────────────────────────────────────────────
  const saveBar = el("div", { class: "wizard-section" }, [
    el("div", { class: "wizard-actions" }, [
      el(
        "button",
        {
          class: "btn btn-primary",
          type: "button",
          onclick: async () => {
            // Save all three: declarative config, services, filters
            const [cfgR, svcR, fltR] = await Promise.all([
              api("icp-config-save", { body: { config: cfg } }),
              api("icp-services-save", { body: { services: icpState.services || [] } }),
              api("icp-filters-save", { body: { filters: icpState.filters || [] } }),
            ]);
            if (cfgR?.error) return toast(`❌ Config: ${cfgR.error}`, "err");
            if (svcR?.error) return toast(`❌ Services: ${svcR.error}`, "err");
            if (fltR?.error) return toast(`❌ Filters: ${fltR.error}`, "err");
            toast("Saved — rescoring queued", "ok");
            icpState.status = null;
            icpState.tab = "overview";
            setTimeout(() => renderIcp(), 1500);
          },
        },
        "💾 Save all & rescore",
      ),
      el(
        "button",
        {
          class: "btn btn-secondary",
          type: "button",
          onclick: async () => {
            if (!(icpState.services || []).length) {
              toast("Add services first (or run auto-configure)", "err");
              return;
            }
            toast("Regenerating filters with Claude (10–20s)…", "info");
            const r = await api("icp-filters-generate", {
              body: { services: icpState.services, websiteSummary: icpState._autoSummary || "" },
            });
            if (r?.error) return toast(`❌ ${r.error}`, "err");
            icpState.filters = r.filters || [];
            toast(`✅ ${r.count} filters regenerated — review & save`, "ok");
            renderIcp();
          },
        },
        "↻ Regenerate filters from services",
      ),
    ]),
  ]);
  body.appendChild(saveBar);

  // No return — caller already appended `body` to content
  return;
}

// Renders the services panel. Edits `icpState.services` in place.
function renderIcpServicesPanel() {
  const section = el("div", { class: "wizard-section" }, [
    el("div", { class: "wizard-section-title" }, "Your services"),
    el(
      "div",
      { class: "muted small", style: "margin-bottom:12px;" },
      "What you sell. Filters will be generated per service. Weights matter when a target fits some services but not others.",
    ),
  ]);
  const services = icpState.services || [];
  if (!services.length) {
    section.appendChild(
      el(
        "div",
        { class: "muted small", style: "margin-bottom:12px;" },
        "No services yet. Use the auto-configure box above, or add one below.",
      ),
    );
  }
  for (let i = 0; i < services.length; i++) {
    const svc = services[i];
    section.appendChild(
      el(
        "div",
        {
          style:
            "border:1px solid var(--bg-3);border-radius:6px;padding:10px;margin-bottom:8px;" +
            (svc.enabled === false ? "opacity:0.5;" : ""),
        },
        [
          el("div", { style: "display:flex;align-items:center;gap:8px;margin-bottom:4px;" }, [
            el("input", {
              class: "wizard-input",
              type: "text",
              value: svc.name || "",
              style: "flex:1;",
              onchange: (e) => {
                services[i].name = e.target.value;
              },
            }),
            el(
              "button",
              {
                type: "button",
                class: `btn btn-tiny ${svc.enabled === false ? "btn-secondary" : "btn-primary"}`,
                onclick: () => {
                  services[i].enabled = svc.enabled === false;
                  renderIcp();
                },
              },
              svc.enabled === false ? "OFF" : "ON",
            ),
            el(
              "button",
              {
                type: "button",
                class: "btn btn-tiny btn-danger",
                onclick: () => {
                  services.splice(i, 1);
                  icpState.services = services;
                  renderIcp();
                },
              },
              "×",
            ),
          ]),
          el(
            "textarea",
            {
              class: "wizard-textarea",
              rows: "2",
              placeholder: "What this service is and who it's for",
              onchange: (e) => {
                services[i].description = e.target.value;
              },
            },
            svc.description || "",
          ),
          el("div", { style: "display:flex;align-items:center;gap:8px;margin-top:4px;" }, [
            el("label", { class: "wizard-label", style: "margin:0;" }, "Weight"),
            el("input", {
              type: "number",
              class: "wizard-input",
              min: "0",
              max: "1",
              step: "0.05",
              value: String(svc.weight ?? 0.3),
              style: "width:80px;",
              onchange: (e) => {
                services[i].weight = Number(e.target.value) || 0.3;
              },
            }),
            el("span", { class: "muted small" }, `id: ${svc.id || "(auto)"}`),
          ]),
        ],
      ),
    );
  }
  section.appendChild(
    el(
      "button",
      {
        class: "btn btn-secondary btn-tiny",
        type: "button",
        onclick: () => {
          const id = `svc_${Date.now().toString(36)}`;
          icpState.services = [
            ...services,
            { id, name: "New service", description: "", weight: 0.3, enabled: true },
          ];
          renderIcp();
        },
      },
      "+ Add service",
    ),
  );
  return section;
}

// Renders the filters panel — AI-generated filter criteria, grouped by service.
function renderIcpFiltersPanel() {
  const filters = icpState.filters || [];
  const services = icpState.services || [];
  const servicesById = new Map(services.map((s) => [s.id, s]));

  const section = el("div", { class: "wizard-section" }, [
    el("div", { class: "wizard-section-title" }, "AI-generated filters"),
    el(
      "div",
      { class: "muted small", style: "margin-bottom:12px;" },
      "Each filter is a service-specific criterion Claude uses to score targets. Toggle off any that don't resonate. Weights control positive-filter contribution to the final score; gates fully disqualify.",
    ),
  ]);

  if (!filters.length) {
    section.appendChild(
      el("div", { class: "empty-state", style: "padding:16px;" }, [
        el("div", { class: "empty-state-title" }, "No filters yet"),
        el(
          "div",
          { class: "empty-state-hint" },
          "Add services above, then hit 'Regenerate filters from services' or use the auto-configure box.",
        ),
      ]),
    );
    return section;
  }

  // Group by primary service (first applies_to value). "Global" bucket for filters that apply to all.
  const groups = new Map();
  for (const f of filters) {
    const primary = (f.applies_to && f.applies_to[0]) || "_global";
    if (!groups.has(primary)) groups.set(primary, []);
    groups.get(primary).push(f);
  }

  for (const [svcId, group] of groups) {
    const svcName =
      servicesById.get(svcId)?.name || (svcId === "_global" ? "Global (applies to all)" : svcId);
    section.appendChild(
      el(
        "div",
        { class: "wizard-label", style: "margin-top:12px;font-weight:600;color:var(--text-1);" },
        svcName,
      ),
    );
    for (const f of group) {
      const idx = filters.indexOf(f);
      section.appendChild(renderIcpFilterRow(f, idx));
    }
  }
  return section;
}

// Render the AI-eval result (per-service rollup + per-filter reasoning).
function renderAiEvalResult(result) {
  const wrap = el("div", {
    style: "margin-top:14px;padding-top:14px;border-top:1px solid var(--bg-3);",
  });

  // Headline score + band
  wrap.appendChild(
    el("div", { style: "display:flex;align-items:center;gap:16px;margin-bottom:12px;" }, [
      el("div", { style: "font-size:38px;font-weight:700;" }, String(result.final0to10 || 0)),
      el("div", { class: "muted" }, "/ 10"),
      renderIcpBandBadge(result.band),
    ]),
  );

  if (result.disqualifiedBy && result.disqualifiedBy.length) {
    wrap.appendChild(
      el(
        "div",
        { class: "badge badge-red", style: "margin-bottom:8px;" },
        `Disqualified by: ${result.disqualifiedBy.join(", ")}`,
      ),
    );
  }

  // Per-service breakdown (what it's good for, what it's not)
  const perSvc = result.per_service || {};
  const svcIds = Object.keys(perSvc);
  if (svcIds.length) {
    const svcWrap = el("div", { style: "margin-bottom:12px;" }, [
      el("div", { class: "wizard-label", style: "margin-bottom:6px;" }, "Fit by service"),
    ]);
    for (const sid of svcIds) {
      const s = perSvc[sid];
      svcWrap.appendChild(
        el("div", { style: "display:flex;align-items:center;gap:10px;margin-bottom:4px;" }, [
          el("div", { style: "min-width:180px;" }, s.name || sid),
          renderIcpScoreBar10(s.score, bandForLocal(s.score, icpState.config?.band_thresholds)),
          el("span", { class: "muted small" }, `(${s.filters_considered} filters)`),
        ]),
      );
    }
    wrap.appendChild(svcWrap);
  }

  // Per-filter verdicts with reasoning
  const verdicts = result.breakdown?.positive_verdicts || [];
  const gates = result.breakdown?.gate_verdicts || [];

  if (gates.length) {
    wrap.appendChild(
      el("div", { class: "wizard-label", style: "margin-top:12px;" }, "Gate checks"),
    );
    for (const g of gates) {
      const pass = (g.score ?? 0) > 0.5;
      wrap.appendChild(
        el(
          "div",
          {
            style:
              "display:flex;gap:10px;padding:6px;border-left:3px solid " +
              (pass ? "var(--green)" : "var(--red)") +
              ";margin-bottom:4px;",
          },
          [
            el("div", { style: "min-width:160px;font-weight:600;font-size:12px;" }, g.name || g.id),
            el("div", { class: "muted small" }, g.reasoning || "(no reasoning)"),
          ],
        ),
      );
    }
  }

  if (verdicts.length) {
    wrap.appendChild(
      el("div", { class: "wizard-label", style: "margin-top:12px;" }, "Positive-filter verdicts"),
    );
    // Sort by weighted contribution DESC
    const sorted = [...verdicts].sort((a, b) => b.weight * b.score - a.weight * a.score);
    for (const v of sorted) {
      const pct = Math.round((v.score || 0) * 100);
      const contribution = Math.round((v.weight || 0) * (v.score || 0) * 100) / 10;
      wrap.appendChild(
        el(
          "div",
          {
            style:
              "padding:6px;border-left:3px solid " +
              (v.score >= 0.7 ? "var(--green)" : v.score <= 0.3 ? "var(--red)" : "var(--text-4)") +
              ";margin-bottom:4px;",
          },
          [
            el("div", { style: "display:flex;align-items:center;gap:10px;margin-bottom:2px;" }, [
              el("div", { style: "flex:1;font-weight:600;font-size:12px;" }, v.name || v.id),
              el("div", { class: "muted small mono" }, `${pct}% · +${contribution} pts`),
            ]),
            el("div", { class: "muted small" }, v.reasoning || "(no reasoning)"),
          ],
        ),
      );
    }
  }
  return wrap;
}

function bandForLocal(score, thresholds = [4, 6, 8]) {
  const s = Number(score) || 0;
  const [t1, t2, t3] = thresholds;
  if (s <= t1) return "bin";
  if (s <= t2) return "inbound";
  if (s <= t3) return "outbound";
  return "abm";
}

function renderIcpFilterRow(f, idx) {
  const isGate = f.kind === "gate";
  const filters = icpState.filters;
  return el(
    "div",
    {
      style:
        `border:1px solid ${isGate ? "var(--red)" : "var(--bg-3)"};border-radius:6px;padding:10px;margin-bottom:6px;` +
        (f.enabled === false ? "opacity:0.5;" : "") +
        (isGate ? "background:var(--red-soft);" : ""),
    },
    [
      el("div", { style: "display:flex;align-items:center;gap:8px;margin-bottom:4px;" }, [
        el(
          "span",
          { class: `badge ${isGate ? "badge-red" : "badge-purple"} small` },
          isGate ? "GATE" : "POSITIVE",
        ),
        el("div", { style: "flex:1;font-weight:600;" }, f.name || f.id),
        el(
          "button",
          {
            type: "button",
            class: `btn btn-tiny ${f.enabled === false ? "btn-secondary" : "btn-primary"}`,
            onclick: () => {
              filters[idx].enabled = f.enabled === false;
              renderIcp();
            },
          },
          f.enabled === false ? "OFF" : "ON",
        ),
        el("input", {
          type: "number",
          class: "wizard-input",
          min: "0",
          max: "1",
          step: "0.05",
          value: String(f.weight ?? 0.1),
          style: "width:70px;",
          disabled: isGate,
          title: isGate ? "Gates don't use weights" : "Contribution weight",
          onchange: (e) => {
            filters[idx].weight = Number(e.target.value) || 0.1;
          },
        }),
        el(
          "button",
          {
            type: "button",
            class: "btn btn-tiny btn-danger",
            onclick: () => {
              filters.splice(idx, 1);
              icpState.filters = filters;
              renderIcp();
            },
          },
          "×",
        ),
      ]),
      el("div", { class: "muted small", style: "margin-bottom:4px;" }, f.description || ""),
      f.evaluation_hint
        ? el("details", {}, [
            el("summary", { class: "muted small", style: "cursor:pointer;" }, "What Claude checks"),
            el(
              "div",
              { class: "muted small", style: "margin-top:4px;white-space:pre-wrap;" },
              f.evaluation_hint,
            ),
          ])
        : null,
    ],
  );
}
