<script lang="ts">
  import { onMount } from 'svelte';
  import { appRpc } from '../rpc.ts';
  import { THEMES, THEME_GROUPS, getPalette, type ThemeId, type ThemeMeta } from '../themes.ts';
  import { themeStore } from '../theme-store.svelte.ts';
  import { fontStore } from '../font-store.svelte.ts';
  import ThemeEditor from './ThemeEditor.svelte';

  const UI_FONTS = [
    { value: '',               label: 'System Default' },
    { value: 'Inter',          label: 'Inter' },
    { value: 'IBM Plex Sans',  label: 'IBM Plex Sans' },
    { value: 'Noto Sans',      label: 'Noto Sans' },
    { value: 'Roboto',         label: 'Roboto' },
    { value: 'Ubuntu',         label: 'Ubuntu' },
  ];

  const TERM_FONTS = [
    { value: '',                label: 'Default (JetBrains Mono)' },
    { value: 'JetBrains Mono', label: 'JetBrains Mono' },
    { value: 'Fira Code',      label: 'Fira Code' },
    { value: 'Cascadia Code',  label: 'Cascadia Code' },
    { value: 'Source Code Pro', label: 'Source Code Pro' },
    { value: 'IBM Plex Mono',  label: 'IBM Plex Mono' },
    { value: 'monospace',      label: 'monospace' },
  ];

  // ── Local reactive state ───────────────────────────────────────────────────
  let themeId      = $state<ThemeId>(themeStore.currentTheme);
  let uiFont       = $state(fontStore.uiFontFamily);
  let uiFontSize   = $state(fontStore.uiFontSize);
  let termFont     = $state(fontStore.termFontFamily);
  let termFontSize = $state(fontStore.termFontSize);
  let cursorStyle  = $state('block');
  let cursorBlink  = $state(true);
  let scrollback   = $state(1000);

  interface CustomThemeMeta { id: string; name: string; }
  let customThemes = $state<CustomThemeMeta[]>([]);
  let showEditor   = $state(false);

  // Keep local state in sync when store changes
  $effect(() => { themeId = themeStore.currentTheme; });
  $effect(() => { uiFont = fontStore.uiFontFamily; });
  $effect(() => { uiFontSize = fontStore.uiFontSize; });
  $effect(() => { termFont = fontStore.termFontFamily; });
  $effect(() => { termFontSize = fontStore.termFontSize; });

  // ── Dropdown open state ────────────────────────────────────────────────────
  let themeOpen    = $state(false);
  let uiFontOpen   = $state(false);
  let termFontOpen = $state(false);

  // ── All themes (built-in + custom) ────────────────────────────────────────
  let allThemes = $derived<ThemeMeta[]>([
    ...THEMES,
    ...customThemes.map(t => ({ id: t.id as ThemeId, label: t.name, group: 'Custom', isDark: true })),
  ]);
  let allGroups = $derived([...THEME_GROUPS, ...(customThemes.length > 0 ? ['Custom'] : [])]);

  // ── Derived labels ─────────────────────────────────────────────────────────
  let themeLabel    = $derived(allThemes.find(t => t.id === themeId)?.label ?? 'Catppuccin Mocha');
  let uiFontLabel   = $derived(UI_FONTS.find(f => f.value === uiFont)?.label ?? 'System Default');
  let termFontLabel = $derived(TERM_FONTS.find(f => f.value === termFont)?.label ?? 'Default (JetBrains Mono)');

  // ── Actions ────────────────────────────────────────────────────────────────

  function selectTheme(id: ThemeId): void {
    themeId = id; themeOpen = false;
    themeStore.setTheme(id);
    appRpc?.request['settings.set']({ key: 'theme', value: id }).catch(console.error);
  }

  function selectUIFont(value: string): void {
    uiFont = value; uiFontOpen = false;
    fontStore.setUIFont(value, uiFontSize);
  }

  function selectTermFont(value: string): void {
    termFont = value; termFontOpen = false;
    fontStore.setTermFont(value, termFontSize);
  }

  function adjustUISize(delta: number): void {
    uiFontSize = Math.max(8, Math.min(24, uiFontSize + delta));
    fontStore.setUIFont(uiFont, uiFontSize);
  }

  function adjustTermSize(delta: number): void {
    termFontSize = Math.max(8, Math.min(24, termFontSize + delta));
    fontStore.setTermFont(termFont, termFontSize);
  }

  function persistCursorStyle(v: string) {
    cursorStyle = v;
    appRpc?.request['settings.set']({ key: 'cursor_style', value: v }).catch(console.error);
  }

  function persistCursorBlink(v: boolean) {
    cursorBlink = v;
    appRpc?.request['settings.set']({ key: 'cursor_blink', value: String(v) }).catch(console.error);
  }

  function persistScrollback(v: number) {
    scrollback = v;
    appRpc?.request['settings.set']({ key: 'scrollback', value: String(v) }).catch(console.error);
  }

  function closeAll(): void { themeOpen = false; uiFontOpen = false; termFontOpen = false; }
  function handleOutsideClick(e: MouseEvent): void {
    if (!(e.target as HTMLElement).closest('.dd-wrap')) closeAll();
  }

  async function deleteCustomTheme(id: string) {
    await appRpc?.request['themes.deleteCustom']({ id }).catch(console.error);
    customThemes = customThemes.filter(t => t.id !== id);
    if (themeId === id) selectTheme('mocha');
  }

  function onEditorSave(id: string, name: string) {
    customThemes = [...customThemes, { id, name }];
    showEditor = false;
    selectTheme(id as ThemeId);
  }

  function onEditorCancel() { showEditor = false; }

  onMount(async () => {
    if (!appRpc) return;
    const { settings } = await appRpc.request['settings.getAll']({}).catch(() => ({ settings: {} }));
    if (settings['cursor_style']) cursorStyle = settings['cursor_style'];
    if (settings['cursor_blink']) cursorBlink = settings['cursor_blink'] !== 'false';
    if (settings['scrollback'])  scrollback  = parseInt(settings['scrollback'], 10) || 1000;

    const res = await appRpc.request['themes.getCustom']({}).catch(() => ({ themes: [] }));
    customThemes = res.themes.map(t => ({ id: t.id, name: t.name }));
  });
</script>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="section" onclick={handleOutsideClick} onkeydown={e => e.key === 'Escape' && closeAll()}>

  {#if showEditor}
    <ThemeEditor
      baseThemeId={themeId}
      initialPalette={getPalette(themeId)}
      onSave={onEditorSave}
      onCancel={onEditorCancel}
    />
  {:else}

  <h3 class="sh">Theme</h3>
  <div class="field">
    <div class="dd-wrap">
      <button class="dd-btn" onclick={() => { themeOpen = !themeOpen; uiFontOpen = false; termFontOpen = false; }}>
        {themeLabel}
        <svg class="chev" class:open={themeOpen} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {#if themeOpen}
        <ul class="dd-list" role="listbox">
          {#each allGroups as group}
            <li class="dd-group-label" role="presentation">{group}</li>
            {#each allThemes.filter(t => t.group === group) as t}
              <li class="dd-item" class:sel={themeId === t.id}
                role="option" aria-selected={themeId === t.id} tabindex="0"
                onclick={() => selectTheme(t.id)}
                onkeydown={e => (e.key === 'Enter' || e.key === ' ') && selectTheme(t.id)}
              >
                <span class="dd-item-label">{t.label}</span>
                {#if t.group === 'Custom'}
                  <!-- svelte-ignore a11y_no_static_element_interactions -->
                  <span class="del-btn" title="Delete theme"
                    onclick={e => { e.stopPropagation(); deleteCustomTheme(t.id); }}
                    onkeydown={e => e.key === 'Enter' && (e.stopPropagation(), deleteCustomTheme(t.id))}
                    role="button" tabindex="0" aria-label="Delete {t.label}">✕</span>
                {/if}
              </li>
            {/each}
          {/each}
        </ul>
      {/if}
    </div>
    <div class="theme-actions">
      <button class="theme-action-btn" onclick={() => { themeOpen = false; showEditor = true; }}>Edit Theme</button>
      <button class="theme-action-btn" onclick={() => { themeOpen = false; showEditor = true; }}>+ Custom</button>
    </div>
  </div>

  <h3 class="sh">UI Font</h3>
  <div class="field row">
    <div class="dd-wrap flex1">
      <button class="dd-btn" onclick={() => { uiFontOpen = !uiFontOpen; themeOpen = false; termFontOpen = false; }}>
        {uiFontLabel}
        <svg class="chev" class:open={uiFontOpen} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {#if uiFontOpen}
        <ul class="dd-list" role="listbox">
          {#each UI_FONTS as f}
            <li class="dd-item" class:sel={uiFont === f.value} role="option" aria-selected={uiFont === f.value}
              tabindex="0" onclick={() => selectUIFont(f.value)}
              onkeydown={e => (e.key === 'Enter' || e.key === ' ') && selectUIFont(f.value)}
            >{f.label}</li>
          {/each}
        </ul>
      {/if}
    </div>
    <div class="stepper">
      <button onclick={() => adjustUISize(-1)} aria-label="Decrease UI font size">−</button>
      <span>{uiFontSize}px</span>
      <button onclick={() => adjustUISize(1)} aria-label="Increase UI font size">+</button>
    </div>
  </div>

  <h3 class="sh">Terminal Font</h3>
  <div class="field row">
    <div class="dd-wrap flex1">
      <button class="dd-btn" onclick={() => { termFontOpen = !termFontOpen; themeOpen = false; uiFontOpen = false; }}>
        {termFontLabel}
        <svg class="chev" class:open={termFontOpen} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {#if termFontOpen}
        <ul class="dd-list" role="listbox">
          {#each TERM_FONTS as f}
            <li class="dd-item" class:sel={termFont === f.value} role="option" aria-selected={termFont === f.value}
              tabindex="0" onclick={() => selectTermFont(f.value)}
              onkeydown={e => (e.key === 'Enter' || e.key === ' ') && selectTermFont(f.value)}
            >{f.label}</li>
          {/each}
        </ul>
      {/if}
    </div>
    <div class="stepper">
      <button onclick={() => adjustTermSize(-1)} aria-label="Decrease terminal font size">−</button>
      <span>{termFontSize}px</span>
      <button onclick={() => adjustTermSize(1)} aria-label="Increase terminal font size">+</button>
    </div>
  </div>

  <h3 class="sh">Terminal Cursor</h3>
  <div class="field row">
    <div class="seg">
      {#each ['block', 'line', 'underline'] as s}
        <button class:active={cursorStyle === s} onclick={() => persistCursorStyle(s)}>{s[0].toUpperCase() + s.slice(1)}</button>
      {/each}
    </div>
    <label class="toggle-row">
      <span>Blink</span>
      <button class="toggle" class:on={cursorBlink} onclick={() => persistCursorBlink(!cursorBlink)}>{cursorBlink ? 'On' : 'Off'}</button>
    </label>
  </div>

  <h3 class="sh">Scrollback</h3>
  <div class="field row">
    <input type="number" class="num-in" min="100" max="100000" step="100" value={scrollback}
      onchange={e => persistScrollback(parseInt((e.target as HTMLInputElement).value, 10) || 1000)}
      aria-label="Scrollback lines" />
    <span class="hint">lines (100–100k)</span>
  </div>

  {/if}
</div>

<style>
  .section { display: flex; flex-direction: column; gap: 0.5rem; }
  .sh { margin: 0.375rem 0 0.125rem; font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ctp-overlay0); }
  .field { position: relative; }
  .row { display: flex; align-items: center; gap: 0.5rem; }
  .flex1 { flex: 1; min-width: 0; }

  .dd-wrap { position: relative; }
  .dd-btn {
    width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 0.375rem;
    background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem;
    padding: 0.3rem 0.5rem; color: var(--ctp-text); font-family: var(--ui-font-family);
    font-size: 0.8125rem; cursor: pointer; text-align: left;
  }
  .dd-btn:hover { border-color: var(--ctp-surface2); }
  .chev { width: 0.75rem; height: 0.75rem; color: var(--ctp-overlay1); transition: transform 0.15s; flex-shrink: 0; }
  .chev.open { transform: rotate(180deg); }
  .dd-list {
    position: absolute; top: calc(100% + 0.125rem); left: 0; right: 0; z-index: 50;
    list-style: none; margin: 0; padding: 0.25rem;
    background: var(--ctp-mantle); border: 1px solid var(--ctp-surface1); border-radius: 0.3rem;
    max-height: 14rem; overflow-y: auto;
    box-shadow: 0 0.5rem 1rem color-mix(in srgb, var(--ctp-crust) 60%, transparent);
  }
  .dd-group-label {
    padding: 0.25rem 0.5rem 0.125rem; font-size: 0.625rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--ctp-overlay0); border-top: 1px solid var(--ctp-surface0);
  }
  .dd-group-label:first-child { border-top: none; }
  .dd-item {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.3rem 0.5rem; border-radius: 0.2rem; font-size: 0.8125rem; color: var(--ctp-subtext1);
    cursor: pointer; outline: none; list-style: none;
  }
  .dd-item:hover, .dd-item:focus { background: var(--ctp-surface0); color: var(--ctp-text); }
  .dd-item.sel { background: color-mix(in srgb, var(--ctp-mauve) 15%, transparent); color: var(--ctp-mauve); font-weight: 500; }
  .dd-item-label { flex: 1; }
  .del-btn { font-size: 0.7rem; color: var(--ctp-overlay0); padding: 0.1rem 0.2rem; border-radius: 0.15rem; }
  .del-btn:hover { color: var(--ctp-red); background: color-mix(in srgb, var(--ctp-red) 10%, transparent); }

  .theme-actions { display: flex; gap: 0.375rem; margin-top: 0.25rem; }
  .theme-action-btn {
    padding: 0.2rem 0.625rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1);
    border-radius: 0.2rem; color: var(--ctp-subtext1); font-size: 0.75rem; cursor: pointer;
    font-family: var(--ui-font-family);
  }
  .theme-action-btn:hover { background: var(--ctp-surface1); color: var(--ctp-text); }

  .stepper { display: flex; align-items: center; gap: 0.25rem; flex-shrink: 0; }
  .stepper button { width: 1.375rem; height: 1.375rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.2rem; color: var(--ctp-text); font-size: 0.875rem; cursor: pointer; display: flex; align-items: center; justify-content: center; }
  .stepper button:hover { background: var(--ctp-surface1); }
  .stepper span { font-size: 0.8125rem; color: var(--ctp-text); min-width: 2.5rem; text-align: center; }

  .seg { display: flex; border-radius: 0.25rem; overflow: hidden; border: 1px solid var(--ctp-surface1); }
  .seg button { flex: 1; padding: 0.25rem 0.5rem; background: var(--ctp-surface0); border: none; color: var(--ctp-overlay1); font-size: 0.75rem; cursor: pointer; }
  .seg button:hover { background: var(--ctp-surface1); color: var(--ctp-subtext1); }
  .seg button.active { background: var(--ctp-blue); color: var(--ctp-base); }

  .toggle-row { display: flex; align-items: center; gap: 0.375rem; font-size: 0.8125rem; color: var(--ctp-subtext0); cursor: pointer; }
  .toggle { padding: 0.1875rem 0.5rem; background: var(--ctp-surface0); border: none; border-radius: 0.2rem; color: var(--ctp-subtext0); cursor: pointer; font-size: 0.75rem; }
  .toggle.on { background: var(--ctp-green); color: var(--ctp-base); }

  .num-in { width: 5rem; padding: 0.3rem 0.5rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem; color: var(--ctp-text); font-size: 0.8125rem; }
  .num-in:focus { outline: none; border-color: var(--ctp-blue); }
  .hint { font-size: 0.6875rem; color: var(--ctp-overlay0); }
</style>
