<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 { t, getLocale, setLocale, AVAILABLE_LOCALES } from '../i18n.svelte.ts';
  import ThemeEditor from './ThemeEditor.svelte';
  import CustomDropdown from '../ui/CustomDropdown.svelte';

  // Fallback lists — replaced by system detection on mount
  const FALLBACK_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 FALLBACK_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' },
  ];

  let uiFontItems  = $state(FALLBACK_UI_FONTS.map(f => ({ value: f.value, label: f.label })));
  let termFontItems = $state(FALLBACK_TERM_FONTS.map(f => ({ value: f.value, label: f.label })));

  // ── 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(5000);

  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 (managed by CustomDropdown now) ────────────────────

  // ── Language ──────────────────────────────────────────────────────────────
  let currentLocale = $derived(getLocale());
  let langLabel = $derived(AVAILABLE_LOCALES.find(l => l.tag === currentLocale)?.nativeLabel ?? 'English');

  function selectLang(tag: string): void {
    setLocale(tag);
  }

  // ── 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'] : [])]);

  // ── Dropdown items for CustomDropdown ──────────────────────────────────────
  let themeItems = $derived(allThemes.map(t => ({ value: t.id, label: t.label, group: t.group })));
  // uiFontItems and termFontItems are $state — populated by system.fonts on mount
  let langItems = AVAILABLE_LOCALES.map(l => ({ value: l.tag, label: l.nativeLabel }));

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

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

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

  function selectTermFont(value: string): void {
    termFont = value;
    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);
  }

  // CustomDropdown handles its own open/close state

  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) || 5000;

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

    // Detect system fonts
    try {
      const fontRes = await appRpc.request['system.fonts']({});
      if (fontRes.uiFonts.length > 0) {
        uiFontItems = [
          { value: '', label: 'System Default' },
          ...fontRes.uiFonts.map(f => ({
            value: f.family,
            label: f.preferred ? `\u2605 ${f.family}` : f.family,
          })),
        ];
      }
      if (fontRes.monoFonts.length > 0) {
        termFontItems = [
          { value: '', label: 'Default (JetBrains Mono)' },
          ...fontRes.monoFonts.map(f => ({
            value: f.family,
            label: f.isNerdFont ? `\u2B50 ${f.family}` : f.family,
          })),
        ];
      }
    } catch {
      // Keep fallback font lists
    }
  });
</script>

<div class="section">

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

  <h3 class="sh">{t('settings.theme')}</h3>
  <div class="field">
    <CustomDropdown
      items={themeItems}
      selected={themeId}
      onSelect={v => selectTheme(v as ThemeId)}
      groupBy={true}
    />
    <div class="theme-actions">
      <button class="theme-action-btn" onclick={() => showEditor = true}>Edit Theme</button>
      <button class="theme-action-btn" onclick={() => showEditor = true}>+ Custom</button>
    </div>
  </div>

  <h3 class="sh">{t('settings.uiFont')}</h3>
  <div class="field row">
    <div class="flex1">
      <CustomDropdown
        items={uiFontItems}
        selected={uiFont}
        onSelect={v => selectUIFont(v)}
        placeholder="System Default"
      />
    </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">{t('settings.termFont')}</h3>
  <div class="field row">
    <div class="flex1">
      <CustomDropdown
        items={termFontItems}
        selected={termFont}
        onSelect={v => selectTermFont(v)}
        placeholder="Default (JetBrains Mono)"
      />
    </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">{t('settings.termCursor')}</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">{t('settings.scrollback')}</h3>
  <div class="field row">
    <input type="number" class="num-in" min="1000" max="100000" step="500" value={scrollback}
      onchange={e => persistScrollback(parseInt((e.target as HTMLInputElement).value, 10) || 5000)}
      aria-label="Scrollback lines" />
    <span class="hint">{t('settings.scrollbackHint')}</span>
  </div>

  <h3 class="sh">{t('settings.language')}</h3>
  <div class="field">
    <CustomDropdown
      items={langItems}
      selected={currentLocale}
      onSelect={v => selectLang(v)}
    />
  </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; }

  .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>
