<script lang="ts">
  import { open } from "@tauri-apps/plugin-dialog";
  import {
    Check,
    CheckCircle2,
    ChevronDown,
    ChevronRight,
    CircleDashed,
    CloudCog,
    Code2,
    FolderOpen,
    GitCompare,
    GitMerge,
    Languages,
    KeyRound,
    Palette,
    RefreshCw,
    RotateCw,
    Settings2,
    ShieldCheck,
    SlidersHorizontal,
    Terminal,
    Wrench,
    X,
  } from "@lucide/svelte";
  import {
    applyExternalToolPreset,
    defaultExternalToolsSettings,
    externalToolPresets,
    isExternalToolPresetAvailable,
    type ExternalToolKind,
    type ExternalToolPreset,
  } from "../externalTools";
  import { configuredIntegrationCount, defaultGitIntegrationSettings } from "../integrations";
  import type {
    AnalyticsSettings,
    AppAppearance,
    AppLanguage,
    AppTheme,
    CustomThemeColors,
    DetectedExternalTool,
    ExternalToolsSettings,
    GitIntegrationSecretUpdate,
    GitIntegrationSettings,
    ToolOpenMode,
  } from "../types";
  import IntegrationSettingsPage from "./IntegrationSettingsPage.svelte";
  import SelectMenu from "./SelectMenu.svelte";

  type SettingsPage = "general" | "integrations" | "tools";

  interface Props {
    analytics: AnalyticsSettings;
    theme: AppTheme;
    appearance: AppAppearance;
    customTheme: CustomThemeColors;
    language: AppLanguage;
    autoRefresh: boolean;
    externalTools: ExternalToolsSettings;
    integrations: GitIntegrationSettings;
    detectedTools: DetectedExternalTool[];
    detectionPending: boolean;
    detectionUnavailable: boolean;
    onRefreshDetectedTools: () => void | Promise<void>;
    onSave: (settings: AnalyticsSettings, theme: AppTheme, appearance: AppAppearance, customTheme: CustomThemeColors, language: AppLanguage, autoRefresh: boolean, externalTools: ExternalToolsSettings, integrations: GitIntegrationSettings, integrationSecrets: GitIntegrationSecretUpdate[]) => void | Promise<void>;
    onClose: () => void;
  }

  let {
    analytics,
    theme = "system",
    appearance = "modern",
    customTheme = { background: "#cfd5dc", surface: "#e2e6ea", accent: "#2eb5d1", text: "#222328" },
    language = "en",
    autoRefresh = true,
    externalTools,
    integrations,
    detectedTools = [],
    detectionPending = false,
    detectionUnavailable = false,
    onRefreshDetectedTools = () => {},
    onSave = () => {},
    onClose = () => {},
  }: Props = $props();

  const toolKinds: ExternalToolKind[] = ["editor", "diff", "merge", "terminal", "fileManager"];

  let activePage = $state<SettingsPage>("integrations");
  let activeToolKind = $state<ExternalToolKind>("editor");
  let advancedOpen = $state(false);
  let analyticsEnabled = $state(true);
  let selectedTheme = $state<AppTheme>("system");
  let selectedAppearance = $state<AppAppearance>("modern");
  let customColors = $state<CustomThemeColors>({ background: "#cfd5dc", surface: "#e2e6ea", accent: "#2eb5d1", text: "#222328" });
  let selectedLanguage = $state<AppLanguage>("en");
  let autoRefreshEnabled = $state(true);
  let tools = $state<ExternalToolsSettings>(defaultExternalToolsSettings());
  let integrationDraft = $state<GitIntegrationSettings>(defaultGitIntegrationSettings());
  let integrationSecretUpdates = $state<GitIntegrationSecretUpdate[]>([]);
  let saving = $state(false);
  const isGerman = $derived(selectedLanguage === "de");

  $effect(() => {
    analyticsEnabled = analytics.enabled;
    selectedTheme = theme;
    selectedAppearance = appearance;
    customColors = structuredClone(customTheme);
    selectedLanguage = language;
    autoRefreshEnabled = autoRefresh;
    tools = structuredClone(externalTools);
    integrationDraft = structuredClone(integrations);
  });

  async function save() {
    if (saving) return;
    saving = true;
    try {
      await onSave({
        ...analytics,
        enabled: analyticsEnabled,
        noticeSeen: true,
      }, selectedTheme, selectedAppearance, $state.snapshot(customColors), selectedLanguage, autoRefreshEnabled, $state.snapshot(tools), $state.snapshot(integrationDraft), $state.snapshot(integrationSecretUpdates));
    } finally {
      saving = false;
    }
  }

  function resetCustomColors() {
    customColors = selectedTheme === "dark"
      ? { background: "#222328", surface: "#2b2e34", accent: "#2eb5d1", text: "#f0f1f2" }
      : { background: "#cfd5dc", surface: "#e2e6ea", accent: "#2eb5d1", text: "#222328" };
  }

  function cssColorToHex(value: string, fallback: string): string {
    const color = value.trim();
    if (/^#[0-9a-f]{6}$/i.test(color)) return color.toLowerCase();
    if (!color || typeof document === "undefined") return fallback;
    const probe = document.createElement("span");
    probe.style.color = color;
    if (!probe.style.color) return fallback;
    probe.style.display = "none";
    document.body.appendChild(probe);
    const match = getComputedStyle(probe).color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)/i);
    probe.remove();
    if (!match) return fallback;
    return `#${match.slice(1, 4).map((part) => Number(part).toString(16).padStart(2, "0")).join("")}`;
  }

  function currentThemeColors(): CustomThemeColors {
    const styles = getComputedStyle(document.documentElement);
    const fallback = selectedTheme === "dark"
      ? { background: "#222328", surface: "#2b2e34", accent: "#2eb5d1", text: "#f0f1f2" }
      : { background: "#cfd5dc", surface: "#e2e6ea", accent: "#2eb5d1", text: "#222328" };
    return {
      background: cssColorToHex(styles.getPropertyValue("--app-bg"), fallback.background),
      surface: cssColorToHex(styles.getPropertyValue("--color-surface"), fallback.surface),
      accent: cssColorToHex(styles.getPropertyValue("--color-accent"), fallback.accent),
      text: cssColorToHex(styles.getPropertyValue("--color-ink"), fallback.text),
    };
  }

  function selectAppearance(next: AppAppearance) {
    if (next === "custom" && selectedAppearance !== "custom") customColors = currentThemeColors();
    selectedAppearance = next;
  }

  function toolLabel(kind: ExternalToolKind): string {
    const labels = {
      editor: "Editor",
      diff: isGerman ? "Diff-Tool" : "Diff tool",
      merge: isGerman ? "Merge-Tool" : "Merge tool",
      terminal: "Terminal",
      fileManager: isGerman ? "Dateimanager" : "File manager",
    };
    return labels[kind];
  }

  function toolDescription(kind: ExternalToolKind): string {
    const descriptions = isGerman
      ? {
          editor: "Öffnet Repositories und einzelne Dateien zum Bearbeiten.",
          diff: "Vergleicht eine Arbeitsdatei mit ihrer Version aus HEAD.",
          merge: "Übergibt Base, Current, Incoming und Ergebnis an einen 3-Wege-Merger.",
          terminal: "Startet eine Shell direkt im Repository-Verzeichnis.",
          fileManager: "Öffnet das Repository im bevorzugten Dateimanager.",
        }
      : {
          editor: "Opens repositories and individual files for editing.",
          diff: "Compares a working file with its version from HEAD.",
          merge: "Passes base, current, incoming, and result to a three-way merger.",
          terminal: "Starts a shell directly in the repository directory.",
          fileManager: "Opens the repository in your preferred file manager.",
        };
    return descriptions[kind];
  }

  function toolUsage(kind: ExternalToolKind): string {
    const usage = isGerman
      ? {
          editor: "Oben in der Repository-Leiste oder über das Code-Symbol im Datei-Explorer.",
          diff: "Datei im Explorer markieren und das Vergleichs-Symbol anklicken – alternativ Rechtsklick auf die Datei.",
          merge: "Bei einem Konflikt „Konflikte lösen“ öffnen und anschließend dieses Merge-Tool starten.",
          terminal: "Oben in der Repository-Leiste über den Terminal-Button.",
          fileManager: "Oben in der Repository-Leiste über den Ordner-Button.",
        }
      : {
          editor: "Use the repository toolbar or the code button in the file explorer.",
          diff: "Select a file in Explorer and click the compare button, or right-click the file.",
          merge: "Open Resolve conflicts and start this merge tool from the conflict view.",
          terminal: "Use the terminal button in the repository toolbar.",
          fileManager: "Use the folder button in the repository toolbar.",
        };
    return usage[kind];
  }

  function presetAvailable(kind: ExternalToolKind, preset: ExternalToolPreset): boolean {
    return isExternalToolPresetAvailable(kind, preset, detectedTools);
  }

  function availablePresets(kind: ExternalToolKind): ExternalToolPreset[] {
    return externalToolPresets[kind].filter((preset) => presetAvailable(kind, preset));
  }

  function otherPresets(kind: ExternalToolKind): ExternalToolPreset[] {
    return externalToolPresets[kind].filter((preset) => !presetAvailable(kind, preset));
  }

  function selectedPreset(kind: ExternalToolKind): ExternalToolPreset | undefined {
    return externalToolPresets[kind].find((preset) => preset.id === tools[kind].preset);
  }

  function selectedToolName(kind: ExternalToolKind): string {
    return tools[kind].preset === "custom"
      ? tools[kind].program.split(/[\\/]/).pop() || (isGerman ? "Eigenes Programm" : "Custom application")
      : selectedPreset(kind)?.label ?? tools[kind].program;
  }

  function openMode(kind: "diff" | "merge"): ToolOpenMode {
    return kind === "diff" ? tools.diffOpenMode : tools.mergeOpenMode;
  }

  function setOpenMode(kind: "diff" | "merge", mode: ToolOpenMode) {
    if (kind === "diff") tools.diffOpenMode = mode;
    else tools.mergeOpenMode = mode;
  }

  function selectionAvailable(kind: ExternalToolKind): boolean {
    if (tools[kind].preset === "custom") return tools[kind].program.trim().length > 0;
    const preset = selectedPreset(kind);
    return preset ? presetAvailable(kind, preset) : false;
  }

  function selectionStatus(kind: ExternalToolKind): string {
    if (tools[kind].preset === "custom") {
      return tools[kind].program.trim()
        ? (isGerman ? "Manuell konfiguriert" : "Manually configured")
        : (isGerman ? "Programmpfad fehlt" : "Application path missing");
    }
    return selectionAvailable(kind)
      ? (isGerman ? "Installiert und verfügbar" : "Installed and available")
      : (isGerman ? "Nicht automatisch erkannt" : "Not automatically detected");
  }

  function changePreset(kind: ExternalToolKind, id: string) {
    if (id === "custom") {
      tools[kind] = { ...tools[kind], preset: "custom" };
      advancedOpen = true;
      return;
    }
    tools[kind] = applyExternalToolPreset(kind, id, detectedTools);
  }

  function selectToolKind(kind: ExternalToolKind) {
    activeToolKind = kind;
    advancedOpen = tools[kind].preset === "custom";
  }

  function updateProgram(kind: ExternalToolKind, program: string) {
    tools[kind] = { ...tools[kind], preset: "custom", program };
  }

  function updateArgs(kind: ExternalToolKind, value: string) {
    tools[kind] = {
      ...tools[kind],
      preset: "custom",
      args: value.split("\n").map((arg) => arg.trim()).filter(Boolean),
    };
  }

  async function browseProgram(kind: ExternalToolKind) {
    const selected = await open({
      title: isGerman ? `${toolLabel(kind)} auswählen` : `Choose ${toolLabel(kind)}`,
      multiple: false,
      directory: false,
    });
    if (typeof selected === "string") {
      updateProgram(kind, selected);
      advancedOpen = true;
    }
  }
</script>

<div class="dialog-backdrop" role="presentation">
  <div class="dialog app-settings-dialog" role="dialog" aria-modal="true" aria-label={isGerman ? "Einstellungen" : "Settings"} tabindex="-1">
    <header class="app-settings-head">
      <div class="app-settings-title">
        <span class="app-settings-mark"><Settings2 size={18} aria-hidden="true" /></span>
        <div>
          <h2>{isGerman ? "Einstellungen" : "Settings"}</h2>
          <p>{isGerman ? "Gitty an deinen Workflow anpassen" : "Make Gitty fit your workflow"}</p>
        </div>
      </div>
      <button class="dialog-close" type="button" onclick={onClose} title={isGerman ? "Schließen" : "Close"} aria-label={isGerman ? "Einstellungen schließen" : "Close settings"}>
        <X size={18} aria-hidden="true" />
      </button>
    </header>

    <form class="app-settings-shell" onsubmit={(event) => { event.preventDefault(); save(); }}>
      <div class="app-settings-body">
        <nav class="settings-nav" aria-label={isGerman ? "Einstellungsbereiche" : "Settings sections"}>
          <button type="button" class:active={activePage === "general"} onclick={() => { activePage = "general"; }}>
            <SlidersHorizontal size={16} aria-hidden="true" />
            <span>
              <strong>{isGerman ? "Allgemein" : "General"}</strong>
              <small>{isGerman ? "Darstellung & Verhalten" : "Appearance & behavior"}</small>
            </span>
          </button>
          <button type="button" class:active={activePage === "tools"} onclick={() => { activePage = "tools"; }}>
            <Wrench size={16} aria-hidden="true" />
            <span>
              <strong>{isGerman ? "Externe Tools" : "External tools"}</strong>
              <small>{isGerman ? "Editor, Diff & Terminal" : "Editor, diff & terminal"}</small>
            </span>
            {#if !detectionUnavailable}<em>{detectedTools.length}</em>{/if}
          </button>
          <button type="button" class:active={activePage === "integrations"} onclick={() => { activePage = "integrations"; }}>
            <CloudCog size={16} aria-hidden="true" />
            <span>
              <strong>{isGerman ? "Integrationen" : "Integrations"}</strong>
              <small>GitHub, GitLab, Azure DevOps & Gitea</small>
            </span>
            <em>{configuredIntegrationCount(integrationDraft)}</em>
          </button>

          <div class="settings-nav-note">
            {#if activePage === "integrations"}<KeyRound size={15} aria-hidden="true" />{:else}<ShieldCheck size={15} aria-hidden="true" />{/if}
            <p>
              {activePage === "integrations"
                ? (isGerman ? "Tokens werden sicher im Schlüsselbund des Betriebssystems gespeichert." : "Tokens are stored securely in the operating system keychain.")
                : (isGerman ? "Tool-Argumente werden direkt und ohne zusätzliche Shell übergeben." : "Tool arguments are passed directly without an extra shell.")}
            </p>
          </div>
        </nav>

        <div class="settings-content">
          {#if activePage === "general"}
            <div class="settings-page-head">
              <div>
                <h3>{isGerman ? "Allgemein" : "General"}</h3>
                <p>{isGerman ? "Darstellung, Sprache und Hintergrundverhalten." : "Appearance, language, and background behavior."}</p>
              </div>
            </div>

            <div class="general-settings-grid">
              <section class="general-setting-panel">
                <header><Palette size={16} /><div><h4>{isGerman ? "Farbschema" : "Theme"}</h4><p>{isGerman ? "Passend zu deiner Umgebung." : "Match your environment."}</p></div></header>
                <div class="settings-segmented" role="radiogroup" aria-label={isGerman ? "Farbschema" : "Theme"}>
                  <label class:active={selectedTheme === "system"}><input type="radio" bind:group={selectedTheme} value="system" /><span>System</span></label>
                  <label class:active={selectedTheme === "light"}><input type="radio" bind:group={selectedTheme} value="light" /><span>{isGerman ? "Hell" : "Light"}</span></label>
                  <label class:active={selectedTheme === "dark"}><input type="radio" bind:group={selectedTheme} value="dark" /><span>{isGerman ? "Dunkel" : "Dark"}</span></label>
                </div>
              </section>

              <section class="general-setting-panel">
                <header><SlidersHorizontal size={16} /><div><h4>{isGerman ? "Darstellungsstil" : "Design style"}</h4><p>{isGerman ? "Aktuell, klassisch oder selbst gestaltet." : "Current, classic, or designed by you."}</p></div></header>
                <div class="settings-segmented" role="radiogroup" aria-label={isGerman ? "Darstellungsstil" : "Design style"}>
                  <label class:active={selectedAppearance === "modern"}><input type="radio" name="appearance" value="modern" checked={selectedAppearance === "modern"} onchange={() => selectAppearance("modern")} /><span>{isGerman ? "Aktuell" : "Modern"}</span></label>
                  <label class:active={selectedAppearance === "classic"}><input type="radio" name="appearance" value="classic" checked={selectedAppearance === "classic"} onchange={() => selectAppearance("classic")} /><span>{isGerman ? "Klassisch" : "Classic"}</span></label>
                  <label class:active={selectedAppearance === "custom"}><input type="radio" name="appearance" value="custom" checked={selectedAppearance === "custom"} onchange={() => selectAppearance("custom")} /><span>{isGerman ? "Eigene" : "Custom"}</span></label>
                </div>
              </section>

              {#if selectedAppearance === "custom"}
                <section class="general-setting-panel general-setting-wide custom-theme-panel">
                  <header>
                    <Palette size={16} />
                    <div><h4>{isGerman ? "Theme-Generator" : "Theme generator"}</h4><p>{isGerman ? "Erstelle dein eigenes Farbprofil." : "Create your own color profile."}</p></div>
                    <button class="theme-reset-button" type="button" onclick={resetCustomColors}><RotateCw size={13} />{isGerman ? "Zurücksetzen" : "Reset"}</button>
                  </header>
                  <div
                    class="theme-preview"
                    style={`--preview-bg:${customColors.background};--preview-surface:${customColors.surface};--preview-accent:${customColors.accent};--preview-text:${customColors.text};`}
                    aria-label={isGerman ? "Vorschau des eigenen Themes" : "Custom theme preview"}
                  >
                    <span class="theme-preview-sidebar"></span>
                    <span class="theme-preview-content"><i></i><b></b><em></em></span>
                  </div>
                  <div class="theme-color-grid">
                    <label><span>{isGerman ? "Hintergrund" : "Background"}</span><input type="color" bind:value={customColors.background} aria-label={isGerman ? "Hintergrundfarbe" : "Background color"} /><code>{customColors.background}</code></label>
                    <label><span>{isGerman ? "Fläche" : "Surface"}</span><input type="color" bind:value={customColors.surface} aria-label={isGerman ? "Flächenfarbe" : "Surface color"} /><code>{customColors.surface}</code></label>
                    <label><span>{isGerman ? "Akzent" : "Accent"}</span><input type="color" bind:value={customColors.accent} aria-label={isGerman ? "Akzentfarbe" : "Accent color"} /><code>{customColors.accent}</code></label>
                    <label><span>{isGerman ? "Schrift" : "Text"}</span><input type="color" bind:value={customColors.text} aria-label={isGerman ? "Schriftfarbe" : "Text color"} /><code>{customColors.text}</code></label>
                  </div>
                  <p class="theme-generator-note">{isGerman ? "Die Farben werden beim Speichern auf die gesamte Oberfläche angewendet." : "The colors are applied across the interface when you save."}</p>
                </section>
              {/if}

              <section class="general-setting-panel">
                <header><Languages size={16} /><div><h4>{isGerman ? "Sprache" : "Language"}</h4><p>{isGerman ? "Sprache der Oberfläche." : "Language used by the interface."}</p></div></header>
                <div class="settings-segmented settings-language" role="radiogroup" aria-label={isGerman ? "App-Sprache" : "App language"}>
                  <label class:active={selectedLanguage === "en"}><input type="radio" bind:group={selectedLanguage} value="en" /><span>EN · English</span></label>
                  <label class:active={selectedLanguage === "de"}><input type="radio" bind:group={selectedLanguage} value="de" /><span>DE · Deutsch</span></label>
                </div>
              </section>

              <section class="general-setting-panel general-setting-wide">
                <header><RefreshCw size={16} /><div><h4>{isGerman ? "Repository-Aktualisierung" : "Repository refresh"}</h4><p>{isGerman ? "Arbeitsbereich und Remotes aktuell halten." : "Keep the working tree and remotes current."}</p></div></header>
                <label class="settings-switch-row">
                  <span><strong>{isGerman ? "Automatisch aktualisieren" : "Refresh automatically"}</strong><small>{isGerman ? "Branch-Status und Änderungen regelmäßig im Hintergrund prüfen." : "Periodically check branch state and working-tree changes."}</small></span>
                  <input type="checkbox" bind:checked={autoRefreshEnabled} />
                </label>
              </section>

              <section class="general-setting-panel general-setting-wide">
                <header><ShieldCheck size={16} /><div><h4>{isGerman ? "Datenschutz" : "Privacy"}</h4><p>{isGerman ? "Anonyme Produkt- und Fehlerdiagnose." : "Anonymous product and error diagnostics."}</p></div></header>
                <label class="settings-switch-row">
                  <span><strong>{isGerman ? "Anonyme Analytics erlauben" : "Allow anonymous analytics"}</strong><small>{isGerman ? "Keine Pfade, Remotes, Branches, Diffs, Zugangsdaten oder Quelltexte." : "No paths, remotes, branches, diffs, credentials, or source code."}</small></span>
                  <input type="checkbox" bind:checked={analyticsEnabled} />
                </label>
              </section>
            </div>
          {:else if activePage === "tools"}
            <div class="settings-page-head tools-page-head">
              <div>
                <h3>{isGerman ? "Externe Tools" : "External tools"}</h3>
                <p>
                  {detectionUnavailable
                    ? (isGerman ? "Automatische Erkennung ist in dieser Umgebung nicht verfügbar." : "Automatic detection is unavailable in this environment.")
                    : (isGerman ? `${detectedTools.length} installierte Programme erkannt.` : `${detectedTools.length} installed applications detected.`)}
                </p>
              </div>
              <button class="tool-rescan-button" type="button" onclick={onRefreshDetectedTools} disabled={detectionPending}>
                <RotateCw class={detectionPending ? "spin" : ""} size={14} aria-hidden="true" />
                {detectionPending ? (isGerman ? "Erkennung läuft…" : "Detecting…") : (isGerman ? "Neu erkennen" : "Detect again")}
              </button>
            </div>

            <div class="tool-kind-tabs" role="tablist" aria-label={isGerman ? "Tool-Kategorie" : "Tool category"}>
              {#each toolKinds as kind}
                <button type="button" role="tab" aria-selected={activeToolKind === kind} class:active={activeToolKind === kind} onclick={() => selectToolKind(kind)}>
                  {#if kind === "editor"}<Code2 size={16} />
                  {:else if kind === "diff"}<GitCompare size={16} />
                  {:else if kind === "merge"}<GitMerge size={16} />
                  {:else if kind === "terminal"}<Terminal size={16} />
                  {:else}<FolderOpen size={16} />{/if}
                  <span>{toolLabel(kind)}</span>
                  <small class:available={selectionAvailable(kind)}></small>
                </button>
              {/each}
            </div>

            <section class="tool-config-panel" aria-label={`${toolLabel(activeToolKind)} ${isGerman ? "konfigurieren" : "configuration"}`}>
              <div class="tool-config-summary">
                <span class="tool-config-icon">
                  {#if activeToolKind === "editor"}<Code2 size={22} />
                  {:else if activeToolKind === "diff"}<GitCompare size={22} />
                  {:else if activeToolKind === "merge"}<GitMerge size={22} />
                  {:else if activeToolKind === "terminal"}<Terminal size={22} />
                  {:else}<FolderOpen size={22} />{/if}
                </span>
                <div>
                  <h4>{toolLabel(activeToolKind)}</h4>
                  <p>{toolDescription(activeToolKind)}</p>
                </div>
                <span class="tool-status" class:available={selectionAvailable(activeToolKind)}>
                  {#if selectionAvailable(activeToolKind)}<CheckCircle2 size={13} />{:else}<CircleDashed size={13} />{/if}
                  {selectionStatus(activeToolKind)}
                </span>
              </div>

              {#if activeToolKind === "diff" || activeToolKind === "merge"}
                {@const openModeKind = activeToolKind as "diff" | "merge"}
                <div class="tool-route" aria-label={isGerman ? "Aktuelle Standardansicht" : "Current default view"}>
                  <span>{isGerman ? "Standard" : "Default"}</span><ChevronRight size={15} aria-hidden="true" />
                  <strong>{openMode(openModeKind) === "gitty" ? (isGerman ? "Gitty · integriert" : "Gitty · built in") : selectedToolName(activeToolKind)}</strong>
                </div>

                <fieldset class="tool-open-mode">
                  <legend>{isGerman ? "Beim Öffnen verwenden" : "Use when opening"}</legend>
                  <div>
                    <button type="button" class:active={openMode(openModeKind) === "gitty"} aria-pressed={openMode(openModeKind) === "gitty"} onclick={() => setOpenMode(openModeKind, "gitty")}>
                      <span>Gitty</span><small>{isGerman ? "Integrierte Ansicht" : "Built-in view"}</small>
                    </button>
                    <button type="button" class:active={openMode(openModeKind) === "external"} aria-pressed={openMode(openModeKind) === "external"} onclick={() => setOpenMode(openModeKind, "external")}>
                      <span>{selectedToolName(activeToolKind)}</span><small>{isGerman ? "Externes Programm" : "External application"}</small>
                    </button>
                  </div>
                </fieldset>
              {:else}
                <div class="tool-route" aria-label={isGerman ? "Aktuelle Standardzuordnung" : "Current default mapping"}>
                  <span>Gitty</span><ChevronRight size={15} aria-hidden="true" /><strong>{selectedToolName(activeToolKind)}</strong>
                </div>
              {/if}

              <label class="tool-default-field">
                <span>{isGerman ? `Standardprogramm für ${toolLabel(activeToolKind)}` : `Default application for ${toolLabel(activeToolKind)}`}</span>
                <SelectMenu
                  class="tool-preset-select"
                  value={tools[activeToolKind].preset}
                  options={[
                    ...availablePresets(activeToolKind).map((preset) => ({ value: preset.id, label: `Installed - ${preset.label}`, group: isGerman ? "Installiert" : "Installed" })),
                    ...otherPresets(activeToolKind).map((preset) => ({ value: preset.id, label: preset.label, group: isGerman ? "Weitere unterstützte Programme" : "Other supported applications" })),
                    { value: "custom", label: isGerman ? "Eigenes Programm auswählen..." : "Choose a custom application..." },
                  ]}
                  ariaLabel={isGerman ? `Standardprogramm für ${toolLabel(activeToolKind)}` : `Default application for ${toolLabel(activeToolKind)}`}
                  onChange={(value) => changePreset(activeToolKind, value)}
                />
                <small>{isGerman ? "Diese Auswahl wird gespeichert und für alle passenden Aktionen verwendet." : "This selection is saved and used for every matching action."}</small>
              </label>

              <div class="tool-usage-callout">
                <span>{isGerman ? "So öffnest du es" : "How to open it"}</span>
                <p>{toolUsage(activeToolKind)}</p>
              </div>

              <button class="tool-advanced-toggle" type="button" aria-expanded={advancedOpen} onclick={() => { advancedOpen = !advancedOpen; }}>
                <span>{isGerman ? "Programmpfad und Argumente" : "Application path and arguments"}</span>
                {#if advancedOpen}<ChevronDown size={15} />{:else}<ChevronRight size={15} />{/if}
              </button>

              {#if advancedOpen}
                <div class="tool-advanced-panel">
                  <label>
                    <span>{isGerman ? "Programmpfad" : "Application path"}</span>
                    <div class="tool-program-row">
                      <input value={tools[activeToolKind].program} oninput={(event) => updateProgram(activeToolKind, event.currentTarget.value)} spellcheck="false" />
                      <button type="button" onclick={() => browseProgram(activeToolKind)} title={isGerman ? "Programm auswählen" : "Choose application"} aria-label={isGerman ? "Programm auswählen" : "Choose application"}><FolderOpen size={15} /></button>
                    </div>
                  </label>
                  <label>
                    <span>{isGerman ? "Argumente · eine Zeile pro Argument" : "Arguments · one per line"}</span>
                    <textarea value={tools[activeToolKind].args.join("\n")} oninput={(event) => updateArgs(activeToolKind, event.currentTarget.value)} spellcheck="false"></textarea>
                  </label>
                  <p class="tool-placeholders">
                    <span>{isGerman ? "Verfügbare Platzhalter" : "Available placeholders"}</span>
                    <code>{"{repo}"}</code><code>{"{file}"}</code><code>{"{parent}"}</code><code>{"{left}"}</code><code>{"{right}"}</code><code>{"{base}"}</code><code>{"{ours}"}</code><code>{"{theirs}"}</code><code>{"{result}"}</code>
                  </p>
                </div>
              {/if}
            </section>
          {:else}
            <div class="settings-page-head">
              <div>
                <h3>{isGerman ? "Integrationen" : "Integrations"}</h3>
                <p>{isGerman ? "Verbinde Gitty mit deinen Git-Hosting-Diensten." : "Connect Gitty to your Git hosting services."}</p>
              </div>
            </div>
            <IntegrationSettingsPage
              language={selectedLanguage}
              settings={integrationDraft}
              onChange={(next) => { integrationDraft = next; }}
              onSecretsChange={(updates) => { integrationSecretUpdates = updates; }}
            />
          {/if}
        </div>
      </div>

      <footer class="app-settings-footer">
        <span>{isGerman ? "Änderungen werden erst beim Speichern übernommen." : "Changes are applied only after saving."}</span>
        <div>
          <button class="btn-secondary" type="button" onclick={onClose}>{isGerman ? "Abbrechen" : "Cancel"}</button>
          <button class="btn-primary" type="submit" disabled={saving}><Check size={16} aria-hidden="true" />{saving ? (isGerman ? "Wird gespeichert…" : "Saving…") : (isGerman ? "Änderungen speichern" : "Save changes")}</button>
        </div>
      </footer>
    </form>
  </div>
</div>

<style>
  .app-settings-dialog { display: grid; grid-template-rows: auto minmax(0, 1fr); width: min(920px, calc(100vw - 32px)); height: min(720px, calc(100vh - 32px)); overflow: hidden; }
  .app-settings-head { display: flex; align-items: center; justify-content: space-between; min-height: 70px; padding: 14px 18px; border-bottom: 1px solid var(--color-border-subtle); background: var(--app-dialog-chrome); }
  .app-settings-title { display: flex; align-items: center; gap: 12px; min-width: 0; }
  .app-settings-mark { display: grid; place-items: center; width: 38px; height: 38px; border: 1px solid color-mix(in srgb, var(--color-accent) 28%, var(--color-border)); border-radius: 10px; color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 9%, transparent); }
  .app-settings-title h2, .settings-page-head h3, .tool-config-summary h4, .general-setting-panel h4 { margin: 0; color: var(--color-ink); }
  .app-settings-title h2 { font-size: 18px; line-height: 1.2; }
  .app-settings-title p, .settings-page-head p, .tool-config-summary p, .general-setting-panel p { margin: 0; color: var(--color-ink-dim); }
  .app-settings-title p { margin-top: 3px; font-size: 11px; }
  .app-settings-shell { display: grid; min-height: 0; grid-template-rows: minmax(0, 1fr) auto; }
  .app-settings-body { display: grid; min-height: 0; grid-template-columns: 205px minmax(0, 1fr); }
  .settings-nav { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 14px 12px; border-right: 1px solid var(--color-border-subtle); background: color-mix(in srgb, var(--app-dialog-chrome) 72%, var(--app-dialog-bg)); }
  .settings-nav > button { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; width: 100%; min-height: 50px; padding: 8px 10px; border: 1px solid transparent; border-radius: 8px; color: var(--color-ink-dim); background: transparent; text-align: left; }
  .settings-nav > button:hover { color: var(--color-ink); background: var(--color-surface-hover); }
  .settings-nav > button.active { border-color: color-mix(in srgb, var(--color-accent) 28%, var(--color-border)); color: var(--color-ink); background: color-mix(in srgb, var(--color-accent) 9%, var(--color-surface-raised)); box-shadow: inset 2px 0 0 var(--color-accent); }
  .settings-nav button > :global(svg) { color: var(--color-ink-muted); }
  .settings-nav button.active > :global(svg) { color: var(--color-accent); }
  .settings-nav button span { display: grid; min-width: 0; gap: 2px; }
  .settings-nav button strong { font-size: 12px; }
  .settings-nav button small { overflow: hidden; color: var(--color-ink-faint); font-size: 9.5px; text-overflow: ellipsis; white-space: nowrap; }
  .settings-nav button em { display: grid; place-items: center; min-width: 21px; height: 20px; padding-inline: 5px; border-radius: 10px; color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 12%, transparent); font-size: 9px; font-style: normal; font-weight: 800; }
  .settings-nav-note { display: flex; align-items: flex-start; gap: 8px; margin-top: auto; padding: 10px; border-top: 1px solid var(--color-border-subtle); color: var(--color-ink-faint); }
  .settings-nav-note :global(svg) { flex: 0 0 auto; margin-top: 1px; color: var(--color-success); }
  .settings-nav-note p { margin: 0; font-size: 9.5px; line-height: 1.45; }
  .settings-content { min-width: 0; overflow: auto; padding: 18px 20px 22px; }
  .settings-page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
  .settings-page-head h3 { font-size: 18px; }
  .settings-page-head p { margin-top: 4px; font-size: 11px; line-height: 1.45; }
  .tool-rescan-button { display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto; min-height: 30px; padding: 0 10px; border: 1px solid var(--color-border); border-radius: 7px; color: var(--color-ink-muted); background: var(--color-surface-raised); font-size: 10px; font-weight: 750; }
  .tool-rescan-button:hover:not(:disabled) { color: var(--color-ink); border-color: var(--color-border-input); background: var(--color-surface-hover); }
  .tool-kind-tabs { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; margin-bottom: 14px; padding: 4px; border: 1px solid var(--color-border-subtle); border-radius: 10px; background: var(--app-settings-row-bg); }
  .tool-kind-tabs button { position: relative; display: flex; align-items: center; justify-content: center; gap: 7px; min-width: 0; height: 38px; padding: 0 8px; border: 1px solid transparent; border-radius: 7px; color: var(--color-ink-dim); background: transparent; font-size: 10.5px; font-weight: 750; }
  .tool-kind-tabs button:hover { color: var(--color-ink); background: var(--color-surface-hover); }
  .tool-kind-tabs button.active { border-color: var(--color-border-input); color: var(--color-ink); background: var(--color-surface-raised); box-shadow: 0 2px 8px rgba(0,0,0,.12); }
  .tool-kind-tabs button.active :global(svg) { color: var(--color-accent); }
  .tool-kind-tabs button small { position: absolute; top: 5px; right: 6px; width: 5px; height: 5px; border-radius: 50%; background: var(--color-ink-faint); }
  .tool-kind-tabs button small.available { background: var(--color-success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-success) 15%, transparent); }
  .tool-config-panel { display: grid; gap: 14px; padding: 16px; border: 1px solid var(--color-border-subtle); border-radius: 12px; background: color-mix(in srgb, var(--app-settings-row-bg) 72%, transparent); }
  .tool-config-summary { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 11px; }
  .tool-config-icon { display: grid; place-items: center; width: 42px; height: 42px; border: 1px solid color-mix(in srgb, var(--color-accent) 25%, var(--color-border)); border-radius: 10px; color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 8%, transparent); }
  .tool-config-summary h4 { font-size: 14px; }
  .tool-config-summary p { margin-top: 3px; font-size: 10.5px; line-height: 1.4; }
  .tool-status { display: inline-flex; align-items: center; gap: 5px; padding: 5px 7px; border: 1px solid var(--color-border-subtle); border-radius: 6px; color: var(--color-ink-faint); font-size: 9px; font-weight: 750; }
  .tool-status.available { border-color: color-mix(in srgb, var(--color-success) 24%, var(--color-border)); color: var(--color-success); background: color-mix(in srgb, var(--color-success) 6%, transparent); }
  .tool-route { display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 7px 10px; border: 1px solid var(--color-border-subtle); border-radius: 8px; color: var(--color-ink-faint); background: var(--color-surface-raised); font-size: 10.5px; }
  .tool-route strong { color: var(--color-ink); }
  .tool-open-mode { display: grid; gap: 6px; min-width: 0; margin: 0; padding: 0; border: 0; }
  .tool-open-mode legend { margin-bottom: 6px; color: var(--color-ink-muted); font-size: 10.5px; font-weight: 750; }
  .tool-open-mode > div { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; padding: 4px; border: 1px solid var(--color-border-subtle); border-radius: 9px; background: var(--color-surface-raised); }
  .tool-open-mode button { display: grid; justify-items: start; gap: 2px; min-width: 0; min-height: 46px; padding: 7px 10px; border: 1px solid transparent; border-radius: 7px; color: var(--color-ink-dim); background: transparent; text-align: left; }
  .tool-open-mode button:hover { color: var(--color-ink); background: var(--color-surface-hover); }
  .tool-open-mode button.active { border-color: color-mix(in srgb, var(--color-accent) 38%, var(--color-border)); color: var(--color-ink); background: color-mix(in srgb, var(--color-accent) 9%, var(--color-surface-hover)); box-shadow: inset 2px 0 0 var(--color-accent); }
  .tool-open-mode button span { max-width: 100%; overflow: hidden; font-size: 11px; font-weight: 800; text-overflow: ellipsis; white-space: nowrap; }
  .tool-open-mode button small { color: var(--color-ink-faint); font-size: 9px; font-weight: 550; }
  .tool-default-field, .tool-advanced-panel label { display: grid; gap: 6px; min-width: 0; color: var(--color-ink-muted); font-size: 10.5px; font-weight: 750; }
  .tool-advanced-panel input, .tool-advanced-panel textarea { width: 100%; min-width: 0; border: 1px solid var(--color-border); border-radius: 7px; color: var(--color-ink); background: var(--color-surface-raised); font: inherit; }
  :global(.tool-preset-select .select-menu-trigger) { height: 38px; min-height: 38px; padding: 0 11px; border-color: var(--color-border); font-size: 12px; font-weight: 700; }
  .tool-default-field small { color: var(--color-ink-faint); font-size: 9.5px; font-weight: 500; }
  .tool-usage-callout { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 10px; padding: 10px 11px; border-left: 2px solid var(--color-accent); border-radius: 0 7px 7px 0; background: color-mix(in srgb, var(--color-accent) 6%, transparent); }
  .tool-usage-callout span { color: var(--color-accent); font-size: 9.5px; font-weight: 850; text-transform: uppercase; letter-spacing: .04em; }
  .tool-usage-callout p { margin: 0; color: var(--color-ink-muted); font-size: 10.5px; line-height: 1.45; }
  .tool-advanced-toggle { display: flex; align-items: center; justify-content: space-between; min-height: 32px; padding: 0; border: 0; border-top: 1px solid var(--color-border-subtle); color: var(--color-ink-dim); background: transparent; font-size: 10.5px; font-weight: 750; }
  .tool-advanced-toggle:hover { color: var(--color-ink); }
  .tool-advanced-panel { display: grid; gap: 11px; padding-top: 2px; }
  .tool-program-row { display: grid; grid-template-columns: minmax(0, 1fr) 34px; gap: 6px; }
  .tool-advanced-panel input { height: 34px; padding: 0 9px; font-family: var(--font-mono); font-size: 10.5px; }
  .tool-advanced-panel textarea { min-height: 80px; padding: 8px 9px; resize: vertical; font-family: var(--font-mono); font-size: 10.5px; line-height: 1.45; }
  .tool-program-row button { display: grid; place-items: center; border: 1px solid var(--color-border); border-radius: 7px; color: var(--color-ink-muted); background: var(--color-surface-raised); }
  .tool-program-row button:hover { color: var(--color-ink); border-color: var(--color-border-input); background: var(--color-surface-hover); }
  .tool-placeholders { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin: 0; color: var(--color-ink-faint); font-size: 9px; }
  .tool-placeholders span { margin-right: 3px; }
  .tool-placeholders code { padding: 2px 4px; border-radius: 4px; color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 9%, transparent); }
  .general-settings-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .general-setting-panel { display: grid; align-content: start; gap: 14px; min-width: 0; padding: 14px; border: 1px solid var(--color-border-subtle); border-radius: 10px; background: var(--app-settings-row-bg); }
  .general-setting-panel.general-setting-wide { grid-column: 1 / -1; }
  .general-setting-panel > header { display: flex; align-items: flex-start; gap: 9px; }
  .general-setting-panel > header > :global(svg) { flex: 0 0 auto; margin-top: 1px; color: var(--color-accent); }
  .general-setting-panel h4 { font-size: 12.5px; }
  .general-setting-panel p { margin-top: 3px; font-size: 9.5px; }
  .settings-segmented { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 3px; border: 1px solid var(--color-border-subtle); border-radius: 8px; background: var(--color-surface-raised); }
  .settings-segmented.settings-language { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .settings-segmented label { display: flex; align-items: center; justify-content: center; min-height: 31px; border: 1px solid transparent; border-radius: 6px; color: var(--color-ink-dim); font-size: 10.5px; font-weight: 750; }
  .settings-segmented label.active { border-color: var(--color-border-input); color: var(--color-ink); background: var(--color-surface-hover); }
  .settings-segmented input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
  .custom-theme-panel > header { align-items: center; }
  .custom-theme-panel > header > div { min-width: 0; }
  .theme-reset-button { display: inline-flex; align-items: center; gap: 5px; min-height: 27px; margin-left: auto; padding: 0 8px; border: 1px solid var(--color-border); color: var(--color-ink-muted); background: var(--color-surface-raised); font-size: 9.5px; font-weight: 750; }
  .theme-reset-button:hover:not(:disabled) { border-color: var(--color-border-input); color: var(--color-ink); background: var(--color-surface-hover); }
  .theme-preview { display: grid; grid-template-columns: 28% 1fr; min-height: 78px; overflow: hidden; border: 1px solid color-mix(in srgb, var(--preview-text) 30%, var(--preview-surface)); background: var(--preview-bg); }
  .theme-preview-sidebar { border-right: 1px solid color-mix(in srgb, var(--preview-text) 24%, var(--preview-surface)); background: color-mix(in srgb, var(--preview-surface) 86%, var(--preview-bg)); }
  .theme-preview-content { display: grid; grid-template-columns: 1fr auto; align-content: start; gap: 8px; margin: 10px; padding: 10px; border: 1px solid color-mix(in srgb, var(--preview-text) 22%, var(--preview-surface)); color: var(--preview-text); background: var(--preview-surface); }
  .theme-preview-content i { display: block; width: 54%; height: 7px; background: var(--preview-text); opacity: .82; }
  .theme-preview-content b { display: block; width: 34px; height: 18px; grid-row: 1 / 3; grid-column: 2; background: var(--preview-accent); }
  .theme-preview-content em { display: block; width: 76%; height: 5px; background: var(--preview-text); opacity: .32; }
  .theme-color-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; }
  .theme-color-grid label { display: grid; grid-template-columns: minmax(0, 1fr) 32px auto; align-items: center; gap: 8px; min-width: 0; min-height: 38px; padding: 5px 7px; border: 1px solid var(--color-border-subtle); background: var(--color-surface-raised); }
  .theme-color-grid label > span { color: var(--color-ink-muted); font-size: 10px; font-weight: 750; }
  .theme-color-grid input[type="color"] { width: 32px; height: 25px; padding: 2px; border: 1px solid var(--color-border-input); background: transparent; cursor: pointer; }
  .theme-color-grid code { color: var(--color-ink-faint); font: 9px var(--font-mono); text-transform: uppercase; }
  .theme-generator-note { margin: -5px 0 0 !important; color: var(--color-ink-faint) !important; }
  .settings-switch-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 14px; }
  .settings-switch-row span { display: grid; gap: 3px; }
  .settings-switch-row strong { color: var(--color-ink); font-size: 11px; }
  .settings-switch-row small { color: var(--color-ink-dim); font-size: 9.5px; line-height: 1.4; }
  .settings-switch-row input { width: 32px; height: 18px; accent-color: var(--color-accent); }
  .app-settings-footer { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 62px; padding: 11px 16px; border-top: 1px solid var(--color-border-subtle); background: var(--app-dialog-chrome); }
  .app-settings-footer > span { color: var(--color-ink-faint); font-size: 9.5px; }
  .app-settings-footer > div { display: flex; gap: 8px; }
  .app-settings-footer button { min-height: 32px; }

  @media (max-width: 760px) {
    .app-settings-dialog { height: min(760px, calc(100vh - 20px)); width: min(660px, calc(100vw - 20px)); }
    .app-settings-body { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
    .settings-nav { flex-direction: row; padding: 8px 10px; border-right: 0; border-bottom: 1px solid var(--color-border-subtle); }
    .settings-nav > button { width: auto; min-width: 0; flex: 1 1 0; min-height: 42px; }
    .settings-nav-note { display: none; }
    .settings-content { padding: 14px; }
    .tool-kind-tabs { grid-template-columns: repeat(5, minmax(42px, 1fr)); overflow-x: auto; }
    .tool-kind-tabs button { height: 40px; }
    .tool-kind-tabs button span { display: none; }
    .tool-config-summary { grid-template-columns: auto minmax(0, 1fr); }
    .tool-status { grid-column: 1 / -1; justify-self: start; }
    .app-settings-footer > span { display: none; }
    .app-settings-footer { justify-content: flex-end; }
  }

  @media (max-width: 520px) {
    .app-settings-head { min-height: 58px; padding: 10px 12px; }
    .app-settings-mark { width: 34px; height: 34px; }
    .settings-nav button small, .settings-nav button em { display: none; }
    .settings-nav > button { grid-template-columns: auto minmax(0, 1fr); gap: 5px; padding-inline: 6px; }
    .settings-nav button strong { font-size: 10px; }
    .settings-page-head { align-items: stretch; flex-direction: column; }
    .tool-rescan-button { align-self: flex-start; }
    .general-settings-grid { grid-template-columns: 1fr; }
    .general-setting-panel.general-setting-wide { grid-column: auto; }
    .theme-color-grid { grid-template-columns: 1fr; }
    .tool-config-panel { padding: 13px; }
    .tool-usage-callout { grid-template-columns: 1fr; gap: 4px; }
  }
</style>
