<script>
  import { onMount } from "svelte";
  import {
    Plus, Trash2, Save, Shield, ChevronRight, X,
    Lock, AlertTriangle, SlidersHorizontal,
  } from "@lucide/svelte";
  import Select from "./comps/Select.svelte";
  import Badge from "./comps/Badge.svelte";
  import InfoTip from "./comps/InfoTip.svelte";

  // ── Shared ────────────────────────────────────────────────────────────────
  let loading     = $state(true);
  let error       = $state("");
  let configReadonly = $state(false);
  let selectedView = $state("proxies"); // "proxies" | profile name

  // ── Proxy state ───────────────────────────────────────────────────────────
  let proxies               = $state([]);
  let proxychainsAvailable  = $state(true);
  let proxySaving           = $state(false);
  let proxyMsg              = $state(null);
  let newUrl                = $state("");
  let newUrlError           = $state("");

  // ── Profile state ─────────────────────────────────────────────────────────
  let tools          = $state([]);
  let profiles       = $state([]);
  let profileDetail  = $state(null);
  let profileLoading = $state(false);
  let notesEdit      = $state("");
  let enabledEdit    = $state([]);
  let disabledEdit   = $state([]);
  let rulesSaving    = $state(false);
  let rulesMsg       = $state(null);
  let overrideEdits  = $state({});
  let overrideSaving = $state({});
  let overrideMsg    = $state({});
  let showNewProfile = $state(false);
  let newName        = $state("");
  let newProfileSaving = $state(false);
  let newProfileError  = $state("");

  let overrideToolNames    = $derived(Object.keys(profileDetail?.tools ?? {}));
  let configurableTools    = $derived(tools.filter((t) => t.config_fields?.length > 0));
  let availableForOverride = $derived(configurableTools.filter((t) => !overrideToolNames.includes(t.name)));
  let allToolNames         = $derived(tools.map((t) => t.name));
  let isReadonly           = $derived((profileDetail?.readonly ?? false) || configReadonly);

  onMount(loadAll);

  async function loadAll() {
    loading = true;
    error = "";
    try {
      const [tr, pr, cr] = await Promise.all([
        fetch("/api/tools"),
        fetch("/api/config/profiles"),
        fetch("/api/config"),
      ]);
      if (!tr.ok) throw new Error(`HTTP ${tr.status}`);
      if (!pr.ok) throw new Error(`HTTP ${pr.status}`);
      tools    = await tr.json();
      profiles = await pr.json();
      if (cr.ok) {
        const cfg    = await cr.json();
        configReadonly       = cfg.readonly               ?? false;
        proxies              = cfg.proxies                ?? [];
        proxychainsAvailable = cfg.proxychains_available  ?? true;
      }
    } catch (e) {
      error = e.message;
    } finally {
      loading = false;
    }
  }

  // ── Proxy helpers ─────────────────────────────────────────────────────────
  function validateProxyUrl(url) {
    if (!url) return "URL is required";
    try {
      const u = new URL(url);
      if (!["socks4:", "socks5:", "http:"].includes(u.protocol))
        return "Protocol must be socks4, socks5, or http";
      if (!u.hostname) return "Missing hostname";
    } catch { return "Invalid URL format"; }
    return "";
  }

  function addProxy() {
    const url = newUrl.trim();
    const err = validateProxyUrl(url);
    if (err) { newUrlError = err; return; }
    if (proxies.some((p) => p.url === url)) { newUrlError = "Already in list"; return; }
    proxies    = [...proxies, { url }];
    newUrl     = "";
    newUrlError = "";
  }

  function removeProxy(i) { proxies = proxies.filter((_, j) => j !== i); }

  async function saveProxies() {
    proxySaving = true;
    proxyMsg    = null;
    try {
      const res = await fetch("/api/config/proxies", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(proxies),
      });
      if (!res.ok)
        throw new Error((await res.json().catch(() => ({}))).error || `HTTP ${res.status}`);
      proxyMsg = { ok: true, text: "Saved" };
      setTimeout(() => (proxyMsg = null), 3000);
    } catch (e) {
      proxyMsg = { ok: false, text: e.message };
    } finally {
      proxySaving = false;
    }
  }

  function proxyLabel(url) {
    try {
      const u = new URL(url);
      const proto = u.protocol.replace(":", "").toUpperCase();
      const auth  = u.username ? `${u.username}@` : "";
      const port  = u.port || (u.protocol === "http:" ? "8080" : "1080");
      return { proto, host: `${auth}${u.hostname}:${port}` };
    } catch { return { proto: "?", host: url }; }
  }

  const PROTO_COLOR = { SOCKS5: "badge-primary", SOCKS4: "badge-secondary", HTTP: "badge-neutral" };

  // ── Profile helpers ───────────────────────────────────────────────────────
  async function selectProfile(name) {
    selectedView   = name;
    profileLoading = true;
    profileDetail  = null;
    overrideEdits  = {};
    overrideSaving = {};
    overrideMsg    = {};
    rulesMsg       = null;
    try {
      const res = await fetch(`/api/config/profiles/${encodeURIComponent(name)}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      profileDetail = await res.json();
      notesEdit    = profileDetail.notes     ?? "";
      enabledEdit  = [...(profileDetail.enabled  ?? [])];
      disabledEdit = [...(profileDetail.disabled ?? [])];
      const nextEdits = {};
      for (const [tn, tc] of Object.entries(profileDetail.tools ?? {})) {
        const tool = tools.find((t) => t.name === tn);
        if (!tool?.config_fields?.length) continue;
        nextEdits[tn] = {};
        for (const f of tool.config_fields)
          nextEdits[tn][f.name] = tc?.[f.name] !== undefined ? tc[f.name] : (f.default ?? "");
      }
      overrideEdits = nextEdits;
    } catch (e) { error = e.message; }
    finally { profileLoading = false; }
  }

  function validateNewName(name) {
    if (!name) return "Name is required";
    if (!/^[a-z0-9-]+$/.test(name)) return "Only a-z, 0-9 and hyphens";
    return "";
  }

  async function createProfile() {
    const name = newName.trim();
    const nameError = validateNewName(name);
    if (nameError) { newProfileError = nameError; return; }
    newProfileSaving = true;
    newProfileError  = "";
    try {
      const res = await fetch("/api/config/profiles", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name }),
      });
      if (!res.ok)
        throw new Error((await res.json().catch(() => ({}))).error || `HTTP ${res.status}`);
      showNewProfile = false;
      newName = "";
      await loadAll();
      await selectProfile(name);
    } catch (e) { newProfileError = e.message; }
    finally { newProfileSaving = false; }
  }

  async function deleteProfile(name) {
    if (!confirm(`Delete profile "${name}"?`)) return;
    try {
      await fetch(`/api/config/profiles/${encodeURIComponent(name)}`, { method: "DELETE" });
      if (selectedView === name) { selectedView = "proxies"; profileDetail = null; }
      await loadAll();
    } catch (e) { error = e.message; }
  }

  async function saveRules() {
    rulesSaving = true;
    rulesMsg    = null;
    try {
      const res = await fetch(`/api/config/profiles/${encodeURIComponent(selectedView)}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ enabled: enabledEdit, disabled: disabledEdit, notes: notesEdit }),
      });
      if (!res.ok)
        throw new Error((await res.json().catch(() => ({}))).error || `HTTP ${res.status}`);
      rulesMsg = { ok: true, text: "Saved" };
      setTimeout(() => (rulesMsg = null), 3000);
      await selectProfile(selectedView);
    } catch (e) { rulesMsg = { ok: false, text: e.message }; }
    finally { rulesSaving = false; }
  }

  async function saveOverride(toolName) {
    const tool = tools.find((t) => t.name === toolName);
    for (const f of tool?.config_fields ?? []) {
      if (f.required) {
        const v = overrideEdits[toolName]?.[f.name];
        if (v === undefined || v === null || v === "") {
          flashOverride(toolName, { ok: false, text: `"${f.name}" is required` });
          return;
        }
      }
    }
    overrideSaving = { ...overrideSaving, [toolName]: true };
    overrideMsg    = { ...overrideMsg,    [toolName]: null  };
    try {
      const res = await fetch(
        `/api/config/profiles/${encodeURIComponent(selectedView)}/tools/${encodeURIComponent(toolName)}`,
        { method: "PATCH", headers: { "Content-Type": "application/json" },
          body: JSON.stringify(overrideEdits[toolName]) }
      );
      if (!res.ok)
        throw new Error((await res.json().catch(() => ({}))).error || `HTTP ${res.status}`);
      flashOverride(toolName, { ok: true, text: "Saved" });
    } catch (e) { flashOverride(toolName, { ok: false, text: e.message }); }
    finally { overrideSaving = { ...overrideSaving, [toolName]: false }; }
  }

  async function deleteOverride(toolName) {
    if (!confirm(`Remove "${toolName}" override from "${selectedView}"?`)) return;
    try {
      await fetch(
        `/api/config/profiles/${encodeURIComponent(selectedView)}/tools/${encodeURIComponent(toolName)}`,
        { method: "DELETE" }
      );
      await selectProfile(selectedView);
    } catch (e) { error = e.message; }
  }

  function addOverrideFor(toolName) {
    if (!toolName) return;
    const tool = tools.find((t) => t.name === toolName);
    if (!tool) return;
    const toolEdits = {};
    for (const f of tool.config_fields ?? []) toolEdits[f.name] = f.default ?? "";
    overrideEdits = { ...overrideEdits, [toolName]: toolEdits };
    profileDetail = { ...profileDetail, tools: { ...(profileDetail.tools ?? {}), [toolName]: {} } };
  }

  function flashOverride(toolName, val) {
    overrideMsg = { ...overrideMsg, [toolName]: val };
    setTimeout(() => { overrideMsg = { ...overrideMsg, [toolName]: null }; }, 3000);
  }
</script>

{#if loading}
  <div class="flex justify-center py-20">
    <span class="loading loading-spinner loading-lg"></span>
  </div>
{:else if error}
  <div class="alert alert-error gap-3"><AlertTriangle size={18} class="shrink-0" />{error}</div>
{:else}
  <div class="flex flex-col md:flex-row gap-0 items-start">

    <!-- ── Sidebar ──────────────────────────────────────────────────────── -->
    <aside class="w-full md:w-56 shrink-0 flex flex-col gap-1
                  border-b border-base-300 pb-4 mb-4
                  md:border-b-0 md:border-r md:pb-0 md:mb-0 md:pr-4 md:mr-6">

      <!-- Proxies entry -->
      <p class="text-xs uppercase tracking-widest text-base-content/40 px-2 mb-1">Global</p>
      <button
        class="flex items-center gap-2 w-full btn btn-sm
               {selectedView === 'proxies' ? 'btn-primary' : 'btn-ghost'} justify-start"
        onclick={() => { selectedView = 'proxies'; profileDetail = null; }}
      >
        {#if selectedView === 'proxies'}
          <ChevronRight size={13} class="shrink-0" />
        {:else}
          <span class="size-[13px] shrink-0"></span>
        {/if}
        <Shield size={13} class="shrink-0" />
        Proxies
        {#if proxies.length > 0}
          <span class="badge badge-xs badge-primary ml-auto">{proxies.length}</span>
        {/if}
      </button>

      <div class="divider my-1 text-xs text-base-content/40">
        <div class="flex items-center gap-2 w-full justify-between">
          <span class="uppercase tracking-widest text-[10px]">Profiles</span>
          {#if !configReadonly}
            <button
              class="btn btn-ghost btn-xs"
              title="New profile"
              onclick={() => { showNewProfile = !showNewProfile; newName = ""; newProfileError = ""; }}
            >
              <Plus size={13} />
            </button>
          {/if}
        </div>
      </div>

      <!-- New profile inline form -->
      {#if showNewProfile && !configReadonly}
        <div class="flex flex-col gap-2 p-2 bg-base-300 rounded-box mb-1">
          <input
            type="text"
            class="input input-bordered input-xs w-full font-mono
                   {newProfileError && !/^[a-z0-9-]*$/.test(newName) ? 'input-error' : ''}"
            placeholder="profile-name"
            bind:value={newName}
            onkeydown={(e) => e.key === 'Enter' && createProfile()}
          />
          {#if newProfileError}
            <p class="text-[11px] text-error">{newProfileError}</p>
          {/if}
          <button
            class="btn btn-primary btn-xs w-full"
            onclick={createProfile}
            disabled={newProfileSaving || !newName.trim()}
          >
            {#if newProfileSaving}
              <span class="loading loading-spinner loading-xs"></span>
            {:else}
              Create
            {/if}
          </button>
        </div>
      {/if}

      <!-- Profile list -->
      {#each profiles as p}
        <div class="flex items-center gap-1 group">
          <button
            class="flex-1 btn btn-sm justify-start gap-1 truncate
                   {selectedView === p.name ? 'btn-primary' : 'btn-ghost'}"
            onclick={() => selectProfile(p.name)}
          >
            {#if selectedView === p.name}
              <ChevronRight size={13} class="shrink-0" />
            {:else}
              <span class="size-[13px] shrink-0"></span>
            {/if}
            {#if p.readonly}
              <Lock size={10} class="shrink-0 opacity-40" />
            {/if}
            <span class="truncate">{p.name}</span>
          </button>
          {#if !p.readonly}
            <button
              class="btn btn-ghost btn-xs text-error opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
              onclick={() => deleteProfile(p.name)}
            >
              <Trash2 size={12} />
            </button>
          {/if}
        </div>
      {/each}

      {#if profiles.length === 0}
        <p class="text-base-content/40 text-xs text-center py-3">No profiles yet.</p>
      {/if}
    </aside>

    <!-- ── Main panel ────────────────────────────────────────────────────── -->
    <div class="flex-1 min-w-0">
      {#if configReadonly}
        <div class="alert alert-warning mb-4 py-2 px-3 text-sm gap-2">
          <Lock size={14} class="shrink-0" />
          Config is managed externally and is read-only.
        </div>
      {/if}

      <!-- ╌╌ Proxy panel ╌╌ -->
      {#if selectedView === 'proxies'}
        <div class="flex flex-col gap-5">

          <div>
            <h2 class="font-bold text-base flex items-center gap-2">
              <Shield size={16} class="text-primary" /> Proxies
            </h2>
            <p class="text-sm text-base-content/50 mt-0.5">
              Route all tool traffic through one or more proxies.
              On network failure the next proxy is tried automatically (round-robin).
              External binaries are wrapped with <code class="font-mono text-xs bg-base-300 px-1 rounded">proxychains4</code>.
            </p>
          </div>

          <!-- proxychains4 missing warning -->
          {#if proxies.length > 0 && !proxychainsAvailable}
            <div class="alert alert-warning py-2 px-3 text-sm gap-2">
              <AlertTriangle size={15} class="shrink-0" />
              <span>
                <strong>proxychains4</strong> not found in PATH, external binary tools
                (maigret, ghunt, etc.) will <strong>not</strong> be proxied.
                Only HTTP-based tools are affected by the proxy config.
              </span>
            </div>
          {/if}

          <!-- Proxy list -->
          <div class="flex flex-col gap-2">
            {#if proxies.length === 0}
              <div class="border border-dashed border-base-300 rounded-box py-8 text-center">
                <Shield size={24} class="mx-auto mb-2 text-base-content/20" />
                <p class="text-sm text-base-content/40">No proxies, tools connect directly.</p>
              </div>
            {:else}
              {#each proxies as proxy, i}
                {@const lbl = proxyLabel(proxy.url)}
                <div class="flex items-center gap-3 bg-base-200 rounded-box px-4 py-2.5
                            border border-base-300 hover:border-base-content/20 transition-colors">
                  <span class="badge badge-sm {PROTO_COLOR[lbl.proto] ?? 'badge-ghost'} font-mono shrink-0">
                    {lbl.proto}
                  </span>
                  <span class="font-mono text-sm flex-1 truncate">{lbl.host}</span>
                  {#if !configReadonly}
                    <button
                      class="btn btn-ghost btn-xs text-error shrink-0"
                      onclick={() => removeProxy(i)}
                    >
                      <Trash2 size={13} />
                    </button>
                  {/if}
                </div>
              {/each}
            {/if}
          </div>

          <!-- Add row -->
          {#if !configReadonly}
            <div class="flex flex-col gap-1.5">
              <div class="flex gap-2">
                <input
                  type="text"
                  class="input input-bordered input-sm font-mono flex-1
                         {newUrlError ? 'input-error' : ''}"
                  placeholder="socks5://user:pass@host:1080"
                  bind:value={newUrl}
                  onkeydown={(e) => e.key === 'Enter' && addProxy()}
                />
                <button
                  class="btn btn-neutral btn-sm gap-1 shrink-0"
                  onclick={addProxy}
                  disabled={!newUrl.trim()}
                >
                  <Plus size={14} /> Add
                </button>
              </div>
              {#if newUrlError}
                <p class="text-xs text-error flex items-center gap-1">
                  <AlertTriangle size={11} />{newUrlError}
                </p>
              {:else}
                <p class="text-xs text-base-content/40">
                  Supported: <span class="font-mono">socks5://</span>,
                  <span class="font-mono">socks4://</span>,
                  <span class="font-mono">http://</span>
                </p>
              {/if}
            </div>

            <div class="flex items-center justify-between pt-1">
              <span></span>
              <div class="flex items-center gap-3">
                {#if proxyMsg}
                  <span class="text-sm {proxyMsg.ok ? 'text-success' : 'text-error'}">{proxyMsg.text}</span>
                {/if}
                <button
                  class="btn btn-primary btn-sm gap-1"
                  onclick={saveProxies}
                  disabled={proxySaving}
                >
                  {#if proxySaving}
                    <span class="loading loading-spinner loading-xs"></span>
                  {:else}
                    <Save size={13} />
                  {/if}
                  Save
                </button>
              </div>
            </div>
          {/if}

        </div>

      <!-- ╌╌ Profile panel ╌╌ -->
      {:else if !selectedView}
        <p class="text-base-content/40 text-sm text-center py-12">Select a profile.</p>

      {:else if profileLoading}
        <div class="flex justify-center py-16">
          <span class="loading loading-spinner loading-md"></span>
        </div>

      {:else if profileDetail}
        <div class="flex flex-col gap-5">

          <!-- Profile header -->
          <div class="flex items-center gap-3 flex-wrap">
            <h2 class="font-bold text-base flex items-center gap-2">
              <SlidersHorizontal size={16} class="text-primary" />
              {#if isReadonly}<Lock size={13} class="text-base-content/40" />{/if}
              {selectedView}
            </h2>
            {#if isReadonly}<Badge text="read-only" size="sm" />{/if}
            {#if profileDetail.active_tools?.length > 0}
              <span class="text-xs text-base-content/50 ml-auto">
                {profileDetail.active_tools.length} active tool{profileDetail.active_tools.length !== 1 ? "s" : ""}
              </span>
            {/if}
          </div>

          <!-- Notes -->
          {#if isReadonly}
            {#if profileDetail.notes}
              <p class="text-sm text-base-content/60 italic">{profileDetail.notes}</p>
            {/if}
          {:else}
            <div class="flex flex-col gap-1">
              <span class="text-xs uppercase tracking-widest text-base-content/40">Notes</span>
              <textarea
                class="textarea textarea-bordered text-sm resize-none"
                placeholder="Describe this profile..."
                rows="2"
                bind:value={notesEdit}
              ></textarea>
            </div>
          {/if}

          <!-- Rules card -->
          <div class="card bg-base-200 border border-base-300">
            <div class="card-body gap-4 p-4">
              <div class="flex items-center justify-between">
                <h3 class="text-xs uppercase tracking-widest text-base-content/40">Rules</h3>
                {#if !isReadonly && rulesMsg}
                  <span class="text-xs {rulesMsg.ok ? 'text-success' : 'text-error'}">{rulesMsg.text}</span>
                {/if}
              </div>

              <div class="flex flex-col gap-2">
                <span class="text-sm font-semibold">
                  Enabled
                  <InfoTip tooltip="If non-empty, only these tools will run for this profile." />
                </span>
                <div class="flex flex-wrap gap-1 items-center min-h-8">
                  {#if isReadonly}
                    {#each (profileDetail.enabled ?? []) as tn}
                      <span class="badge badge-outline gap-1">{tn}</span>
                    {/each}
                    {#if (profileDetail.enabled ?? []).length === 0}
                      <span class="text-xs text-base-content/40">All tools</span>
                    {/if}
                  {:else}
                    {#each enabledEdit as tn}
                      <span class="badge badge-outline gap-1">
                        {tn}
                        <button onclick={() => (enabledEdit = enabledEdit.filter((x) => x !== tn))}>
                          <X size={10} />
                        </button>
                      </span>
                    {/each}
                    <Select
                      options={allToolNames.filter((n) => !enabledEdit.includes(n))}
                      placeholder="add tool" size="xs"
                      onselect={(v) => (enabledEdit = [...enabledEdit, v])}
                    />
                  {/if}
                </div>
              </div>

              <div class="flex flex-col gap-2">
                <span class="text-sm font-semibold">
                  Disabled
                  <InfoTip tooltip="These tools are always skipped, even if they appear in the enabled list." />
                </span>
                <div class="flex flex-wrap gap-1 items-center min-h-8">
                  {#if isReadonly}
                    {#each (profileDetail.disabled ?? []) as tn}
                      <span class="badge badge-error gap-1">{tn}</span>
                    {/each}
                    {#if (profileDetail.disabled ?? []).length === 0}
                      <span class="text-xs text-base-content/40">None</span>
                    {/if}
                  {:else}
                    {#each disabledEdit as tn}
                      <span class="badge badge-error gap-1">
                        {tn}
                        <button onclick={() => (disabledEdit = disabledEdit.filter((x) => x !== tn))}>
                          <X size={10} />
                        </button>
                      </span>
                    {/each}
                    <Select
                      options={allToolNames.filter((n) => !disabledEdit.includes(n))}
                      placeholder="add tool" size="xs"
                      onselect={(v) => (disabledEdit = [...disabledEdit, v])}
                    />
                  {/if}
                </div>
              </div>

              {#if !isReadonly}
                <button
                  class="btn btn-primary btn-sm gap-1 self-start"
                  onclick={saveRules}
                  disabled={rulesSaving}
                >
                  {#if rulesSaving}
                    <span class="loading loading-spinner loading-xs"></span>
                  {:else}
                    <Save size={13} />
                  {/if}
                  Save
                </button>
              {/if}
            </div>
          </div>

          <!-- Overrides card -->
          {#if !isReadonly}
            <div class="card bg-base-200 border border-base-300">
              <div class="card-body gap-4 p-4">
                <div class="flex items-center justify-between gap-2">
                  <h3 class="text-xs uppercase tracking-widest text-base-content/40">Tool overrides</h3>
                  {#if availableForOverride.length > 0}
                    <Select
                      options={availableForOverride.map((t) => t.name)}
                      placeholder="add override" size="xs"
                      onselect={(v) => addOverrideFor(v)}
                    />
                  {/if}
                </div>

                {#if overrideToolNames.length === 0}
                  <p class="text-sm text-base-content/40">No overrides configured.</p>
                {:else}
                  <div class="flex flex-col gap-3">
                    {#each overrideToolNames as toolName}
                      {@const tool = tools.find((t) => t.name === toolName)}
                      <div class="border border-base-300 rounded-box p-3 flex flex-col gap-3">
                        <div class="flex items-center justify-between gap-2">
                          <span class="font-semibold text-sm">{toolName}</span>
                          <div class="flex items-center gap-2">
                            {#if overrideMsg[toolName]}
                              <span class="text-xs {overrideMsg[toolName].ok ? 'text-success' : 'text-error'}">
                                {overrideMsg[toolName].text}
                              </span>
                            {/if}
                            <button
                              class="btn btn-ghost btn-xs text-error"
                              onclick={() => deleteOverride(toolName)}
                            >
                              <Trash2 size={12} />
                            </button>
                          </div>
                        </div>

                        {#if tool?.config_fields?.length && overrideEdits[toolName]}
                          <div class="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-3">
                            {#each tool.config_fields as field}
                              <div class="flex flex-col gap-1">
                                <div class="flex items-center gap-2">
                                  <span class="font-mono text-xs font-semibold">{field.name}</span>
                                  <span class="badge badge-ghost badge-xs">{field.type}</span>
                                  {#if field.required}
                                    <span class="badge badge-error badge-xs">required</span>
                                  {/if}
                                </div>
                                {#if field.type === "bool"}
                                  <label class="flex items-center gap-2 cursor-pointer mt-1">
                                    <input
                                      type="checkbox"
                                      class="toggle toggle-sm toggle-primary"
                                      bind:checked={overrideEdits[toolName][field.name]}
                                    />
                                    <span class="text-xs text-base-content/50">
                                      {overrideEdits[toolName][field.name] ? "enabled" : "disabled"}
                                    </span>
                                  </label>
                                {:else if field.type === "int"}
                                  <input type="number" step="1"
                                    class="input input-bordered input-sm font-mono"
                                    bind:value={overrideEdits[toolName][field.name]} />
                                {:else if field.type === "float"}
                                  <input type="number" step="any"
                                    class="input input-bordered input-sm font-mono"
                                    bind:value={overrideEdits[toolName][field.name]} />
                                {:else if field.type === "enum"}
                                  <select
                                    class="select select-bordered select-sm font-mono"
                                    bind:value={overrideEdits[toolName][field.name]}
                                  >
                                    {#each field.options as opt}
                                      <option value={opt}>{opt}</option>
                                    {/each}
                                  </select>
                                {:else}
                                  <input type="text"
                                    class="input input-bordered input-sm font-mono"
                                    bind:value={overrideEdits[toolName][field.name]} />
                                {/if}
                              </div>
                            {/each}
                          </div>
                          <button
                            class="btn btn-primary btn-sm gap-1 self-start"
                            onclick={() => saveOverride(toolName)}
                            disabled={overrideSaving[toolName]}
                          >
                            {#if overrideSaving[toolName]}
                              <span class="loading loading-spinner loading-xs"></span>
                            {:else}
                              <Save size={13} />
                            {/if}
                            Save
                          </button>
                        {:else}
                          <p class="text-xs text-base-content/40">No configurable fields.</p>
                        {/if}
                      </div>
                    {/each}
                  </div>
                {/if}
              </div>
            </div>
          {/if}

        </div>
      {/if}
    </div>

  </div>
{/if}
