<script lang="ts">
  import { onMount } from 'svelte';
  import { getSetting, setSetting } from '../../adapters/settings-bridge';
  import { getPluginEntries, setPluginEnabled, reloadAllPlugins } from '../../stores/plugins.svelte';
  import { checkForUpdates, getCurrentVersion, getLastCheckTimestamp } from '../../utils/updater';
  import type { UpdateInfo } from '../../utils/updater';
  import { handleError } from '../../utils/handle-error';

  let pluginEntries = $derived(getPluginEntries());
  let pluginAutoUpdate = $state(false);

  let appVersion = $state('');
  let updateLastCheck = $state('');
  let updateChecking = $state(false);
  let updateCheckResult = $state<UpdateInfo | null>(null);

  let relayUrls = $state('');
  let connectionTimeout = $state(30);

  let logLevel = $state<'trace' | 'debug' | 'info' | 'warn' | 'error'>('info');
  let otlpEndpoint = $state('');

  let importFileInput: HTMLInputElement | undefined = $state();
  let loadError = $state('');

  onMount(async () => {
    const results = await Promise.allSettled([
      getCurrentVersion(),
      getSetting('plugin_auto_update'),
      getSetting('relay_urls'),
      getSetting('connection_timeout'),
      getSetting('log_level'),
      getSetting('otlp_endpoint'),
    ]);
    let failCount = 0;
    if (results[0].status === 'fulfilled') appVersion = results[0].value; else failCount++;
    if (results[1].status === 'fulfilled') pluginAutoUpdate = results[1].value === 'true'; else failCount++;
    if (results[2].status === 'fulfilled') relayUrls = results[2].value ?? ''; else failCount++;
    if (results[3].status === 'fulfilled') connectionTimeout = results[3].value ? parseInt(results[3].value, 10) : 30; else failCount++;
    if (results[4].status === 'fulfilled') { const v = results[4].value; if (v === 'trace' || v === 'debug' || v === 'info' || v === 'warn' || v === 'error') logLevel = v; } else failCount++;
    if (results[5].status === 'fulfilled') otlpEndpoint = results[5].value ?? ''; else failCount++;
    if (failCount === results.length) loadError = 'Could not load settings. Displaying defaults.';

    const ts = getLastCheckTimestamp();
    if (ts) updateLastCheck = new Date(ts).toLocaleString();
  });

  async function save(key: string, value: string) {
    try { await setSetting(key, value); } catch (e) { handleError(e, `settings.save.${key}`, 'save your settings'); }
  }

  async function handleCheckForUpdates() {
    updateChecking = true;
    try {
      updateCheckResult = await checkForUpdates();
      const ts = getLastCheckTimestamp();
      if (ts) updateLastCheck = new Date(ts).toLocaleString();
    } catch (e) {
      handleError(e, 'settings.updates.check', 'check for updates');
    } finally {
      updateChecking = false;
    }
  }

  async function handleReloadPlugins() {
    try { await reloadAllPlugins(); } catch (e) { handleError(e, 'settings.plugins.reload', 'reload plugins'); }
  }

  async function handleExport() {
    const keys = [
      'default_shell', 'default_cwd', 'files_save_on_blur', 'theme', 'ui_font_family',
      'ui_font_size', 'term_font_family', 'term_font_size', 'default_permission_mode',
      'system_prompt_template', 'context_pressure_warn', 'context_pressure_critical',
      'budget_monthly_tokens', 'router_profile', 'provider_settings', 'plugin_auto_update',
      'relay_urls', 'connection_timeout', 'log_level', 'otlp_endpoint',
    ];
    const settings: Record<string, string> = {};
    await Promise.all(keys.map(async (k) => {
      const v = await getSetting(k);
      if (v != null) settings[k] = v;
    }));
    const blob = new Blob([JSON.stringify(settings, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'bterminal-settings.json';
    a.click();
    URL.revokeObjectURL(url);
  }

  async function handleImport(e: Event) {
    const input = e.target as HTMLInputElement;
    const file = input.files?.[0];
    if (!file) return;
    try {
      const text = await file.text();
      const imported = JSON.parse(text) as Record<string, string>;
      const sensitive = ['secrets', 'api_key', 'token', 'password'];
      for (const [key, value] of Object.entries(imported)) {
        if (sensitive.some(s => key.toLowerCase().includes(s))) continue;
        if (typeof value === 'string') await setSetting(key, value);
      }
    } catch (err) {
      handleError(err, 'settings.import', 'import settings');
    }
    input.value = '';
  }
</script>

{#if loadError}<p class="load-error">{loadError}</p>{/if}
<section class="section">
  <h2>Plugins</h2>
  {#if pluginEntries.length === 0}
    <p class="empty">No plugins found in ~/.config/agor/plugins/</p>
  {:else}
    <div class="plug-list">
      {#each pluginEntries as entry (entry.meta.id)}
        <div class="plug-row">
          <div class="plug-top">
            <div class="plug-info">
              <span class="plug-name">{entry.meta.name}</span>
              <span class="plug-ver">v{entry.meta.version}</span>
              {#if entry.status === 'loaded'}
                <span class="plug-badge loaded">loaded</span>
              {:else if entry.status === 'error'}
                <span class="plug-badge err" title={entry.error ?? 'Error'}>error</span>
              {:else if entry.status === 'disabled'}
                <span class="plug-badge off">disabled</span>
              {:else}
                <span class="plug-badge disc">discovered</span>
              {/if}
            </div>
            <button class="toggle" class:on={entry.status !== 'disabled'} role="switch"
              aria-checked={entry.status !== 'disabled'} aria-label="Toggle {entry.meta.name}"
              onclick={async () => { await setPluginEnabled(entry.meta.id, entry.status === 'disabled'); }}>
              <span class="thumb"></span>
            </button>
          </div>
          {#if entry.meta.description}
            <p class="plug-desc">{entry.meta.description}</p>
          {/if}
          {#if entry.error}
            <p class="plug-err">{entry.error}</p>
          {/if}
        </div>
      {/each}
    </div>
  {/if}
  <div class="fields" style="margin-top: 0.5rem;">
    <div class="field" id="setting-plugin-auto-update">
      <label class="lbl toggle-row">
        <span>Auto-update plugins</span>
        <button class="toggle" class:on={pluginAutoUpdate} role="switch" aria-checked={pluginAutoUpdate}
          onclick={() => { pluginAutoUpdate = !pluginAutoUpdate; save('plugin_auto_update', String(pluginAutoUpdate)); }}>
          <span class="thumb"></span>
        </button>
      </label>
    </div>
    <button class="btn" onclick={handleReloadPlugins}>Reload Plugins</button>
  </div>
</section>

<section class="section">
  <h2>Updates</h2>
  <div class="fields">
    <div class="field">
      <span class="lbl">Current version</span>
      <span class="val">{appVersion || '...'}</span>
    </div>
    {#if updateLastCheck}
      <div class="field">
        <span class="lbl">Last checked</span>
        <span class="val muted">{updateLastCheck}</span>
      </div>
    {/if}
    {#if updateCheckResult?.available}
      <div class="field">
        <span class="lbl">Available</span>
        <span class="val available">v{updateCheckResult.version}</span>
      </div>
    {/if}
    <button class="btn" onclick={handleCheckForUpdates} disabled={updateChecking}>
      {updateChecking ? 'Checking...' : 'Check for Updates'}
    </button>
  </div>
</section>

<section class="section">
  <h2>Multi-Machine</h2>
  <div class="fields">
    <div class="field" id="setting-relay-urls">
      <label for="adv-relays" class="lbl">Relay URLs (one per line)</label>
      <textarea id="adv-relays" class="ta" value={relayUrls} placeholder="wss://relay.example.com:8443" rows={3}
        onchange={e => { relayUrls = (e.target as HTMLTextAreaElement).value; save('relay_urls', relayUrls); }}></textarea>
      <span class="hint">WebSocket relay endpoints for remote machines</span>
    </div>
    <div class="field">
      <label for="adv-timeout" class="lbl">Connection timeout</label>
      <div class="num-row">
        <input id="adv-timeout" type="number" min="5" max="120" value={connectionTimeout} class="num"
          onchange={e => { const n = parseInt((e.target as HTMLInputElement).value, 10); if (!isNaN(n) && n >= 5 && n <= 120) { connectionTimeout = n; save('connection_timeout', String(n)); } }} />
        <span class="unit">seconds</span>
      </div>
    </div>
  </div>
</section>

<section class="section">
  <h2>Developer / Debug</h2>
  <div class="fields">
    <div class="field" id="setting-log-level">
      <span class="lbl">Log level</span>
      <div class="seg-group">
        {#each ['trace', 'debug', 'info', 'warn', 'error'] as level}
          <button class="seg-btn" class:active={logLevel === level}
            onclick={() => { logLevel = level as typeof logLevel; save('log_level', logLevel); }}>{level}</button>
        {/each}
      </div>
    </div>
    <div class="field" id="setting-otlp">
      <label for="adv-otlp" class="lbl">OTLP endpoint</label>
      <input id="adv-otlp" value={otlpEndpoint} placeholder="http://localhost:4318"
        onchange={e => { otlpEndpoint = (e.target as HTMLInputElement).value; save('otlp_endpoint', otlpEndpoint); }} />
      <span class="hint">OpenTelemetry HTTP endpoint for trace export</span>
    </div>
  </div>
</section>

<section class="section">
  <h2>Import / Export</h2>
  <div class="fields">
    <div class="btn-row">
      <button class="btn" onclick={handleExport}>Export Settings</button>
      <button class="btn" onclick={() => importFileInput?.click()}>Import Settings</button>
      <input bind:this={importFileInput} type="file" accept=".json" style="display:none" onchange={handleImport} />
    </div>
    <span class="hint">Export downloads a JSON file. Import restores non-sensitive settings.</span>
  </div>
</section>

<section class="section">
  <h2>Keyboard Shortcuts</h2>
  <p class="hint-block">Keyboard shortcuts can be customized in <code>~/.claude/keybindings.json</code></p>
</section>

<style>
  .load-error { font-size: 0.75rem; color: var(--ctp-peach); margin: 0 0 0.25rem; }
  h2 { font-size: 0.875rem; font-weight: 600; color: var(--ctp-text); margin: 0 0 0.625rem; padding-bottom: 0.375rem; border-bottom: 1px solid var(--ctp-surface0); }
  .section { margin-bottom: 1.25rem; }
  .fields { display: flex; flex-direction: column; gap: 0.625rem; }
  .field { display: flex; flex-direction: column; gap: 0.25rem; }
  .lbl { font-size: 0.7rem; color: var(--ctp-subtext0); text-transform: uppercase; letter-spacing: 0.03em; }
  .hint { font-size: 0.625rem; color: var(--ctp-overlay0); }
  .val { font-size: 0.8rem; color: var(--ctp-text); }
  .muted { color: var(--ctp-overlay0); }
  .available { color: var(--ctp-green); font-weight: 600; }
  .empty { font-size: 0.75rem; color: var(--ctp-overlay0); margin: 0.25rem 0; }
  input, .ta { padding: 0.375rem 0.625rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem; color: var(--ctp-text); font-size: 0.8rem; }
  .ta { font-family: var(--term-font-family, monospace); resize: vertical; min-height: 3rem; line-height: 1.4; }
  .ta:focus, input:focus { outline: none; border-color: var(--ctp-blue); }
  .ta::placeholder, input::placeholder { color: var(--ctp-overlay0); }
  .toggle-row { display: flex; align-items: center; justify-content: space-between; cursor: pointer; }
  .toggle { position: relative; width: 2rem; height: 1.125rem; border: none; border-radius: 0.5625rem; background: var(--ctp-surface1); cursor: pointer; transition: background 0.2s; padding: 0; flex-shrink: 0; }
  .toggle.on { background: var(--ctp-blue); }
  .thumb { position: absolute; top: 0.125rem; left: 0.125rem; width: 0.875rem; height: 0.875rem; border-radius: 50%; background: var(--ctp-text); transition: transform 0.2s; }
  .toggle.on .thumb { transform: translateX(0.875rem); }
  .seg-group { display: flex; border-radius: 0.25rem; overflow: hidden; border: 1px solid var(--ctp-surface1); }
  .seg-btn { flex: 1; padding: 0.25rem 0.5rem; border: none; background: var(--ctp-surface0); color: var(--ctp-overlay1); font-size: 0.7rem; font-weight: 500; cursor: pointer; transition: background 0.12s, color 0.12s; text-transform: capitalize; }
  .seg-btn:not(:last-child) { border-right: 1px solid var(--ctp-surface1); }
  .seg-btn:hover { background: var(--ctp-surface1); color: var(--ctp-subtext1); }
  .seg-btn.active { background: color-mix(in srgb, var(--ctp-blue) 20%, var(--ctp-surface0)); color: var(--ctp-blue); font-weight: 600; }
  .num-row { display: flex; align-items: center; gap: 0.25rem; }
  .num { width: 4.5rem; padding: 0.375rem 0.625rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem; color: var(--ctp-text); font-size: 0.8rem; -moz-appearance: textfield; }
  .num::-webkit-inner-spin-button, .num::-webkit-outer-spin-button { -webkit-appearance: none; }
  .unit { font-size: 0.7rem; color: var(--ctp-overlay0); }
  .btn { padding: 0.375rem 0.75rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem; color: var(--ctp-text); font-size: 0.75rem; cursor: pointer; transition: background 0.12s; }
  .btn:hover { background: var(--ctp-surface1); }
  .btn:disabled { opacity: 0.5; cursor: not-allowed; }
  .btn-row { display: flex; gap: 0.5rem; }
  .plug-list { display: flex; flex-direction: column; gap: 0.375rem; }
  .plug-row { background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.375rem; padding: 0.5rem 0.625rem; }
  .plug-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
  .plug-info { display: flex; align-items: center; gap: 0.375rem; flex: 1; min-width: 0; }
  .plug-name { font-size: 0.8rem; font-weight: 600; color: var(--ctp-text); white-space: nowrap; }
  .plug-ver { font-size: 0.65rem; color: var(--ctp-overlay0); }
  .plug-badge { padding: 0.0625rem 0.375rem; border-radius: 0.75rem; font-size: 0.575rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; white-space: nowrap; }
  .plug-badge.loaded { background: color-mix(in srgb, var(--ctp-green) 15%, transparent); color: var(--ctp-green); }
  .plug-badge.err { background: color-mix(in srgb, var(--ctp-red) 15%, transparent); color: var(--ctp-red); }
  .plug-badge.off { background: color-mix(in srgb, var(--ctp-overlay0) 15%, transparent); color: var(--ctp-overlay0); }
  .plug-badge.disc { background: color-mix(in srgb, var(--ctp-blue) 15%, transparent); color: var(--ctp-blue); }
  .plug-desc { font-size: 0.7rem; color: var(--ctp-overlay1); margin: 0.25rem 0 0; }
  .plug-err { font-size: 0.65rem; color: var(--ctp-red); margin: 0.25rem 0 0; }
  .hint-block { font-size: 0.75rem; color: var(--ctp-overlay1); margin: 0; line-height: 1.5; }
  .hint-block code { padding: 0.125rem 0.375rem; background: var(--ctp-surface0); border-radius: 0.1875rem; font-family: var(--term-font-family, monospace); font-size: 0.7rem; color: var(--ctp-text); }
</style>
