<script lang="ts">
  import { onMount } from 'svelte';
  import { appRpc } from '../rpc.ts';

  type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';

  const LOG_LEVELS: LogLevel[] = ['trace', 'debug', 'info', 'warn', 'error'];

  interface Plugin { id: string; name: string; version: string; enabled: boolean; }

  let plugins = $state<Plugin[]>([
    { id: 'quanta-plugin', name: 'Quanta Plugin', version: '1.2.0', enabled: true },
    { id: 'session-wrap',  name: 'Session Wrap',  version: '0.4.1', enabled: false },
  ]);

  let logLevel       = $state<LogLevel>('info');
  let otlpEndpoint   = $state('');
  let relayUrls      = $state('');
  let connTimeout    = $state(30);
  let templateDir    = $state('~/.config/agor/templates/');

  let appVersion     = $state('...');
  let updateChecking = $state(false);
  let updateResult   = $state<string | null>(null);
  let updateUrl      = $state<string | null>(null);
  let importError    = $state<string | null>(null);

  function persist(key: string, value: string) {
    appRpc?.request['settings.set']({ key, value }).catch(console.error);
  }

  function setLogLevel(v: LogLevel)  { logLevel = v;      persist('log_level', v); }
  function setOtlp(v: string)        { otlpEndpoint = v;  persist('otlp_endpoint', v); }
  function setRelayUrls(v: string)   { relayUrls = v;     persist('relay_urls', v); }
  function setConnTimeout(v: number) { connTimeout = v;   persist('connection_timeout', String(v)); }
  function setTemplateDir(v: string)  { templateDir = v;  persist('template_dir', v); }

  function togglePlugin(id: string) {
    plugins = plugins.map(p => p.id === id ? { ...p, enabled: !p.enabled } : p);
    const states: Record<string, boolean> = {};
    for (const p of plugins) states[p.id] = p.enabled;
    persist('plugin_states', JSON.stringify(states));
  }

  async function checkForUpdates() {
    if (!appRpc) return;
    updateChecking = true;
    updateResult = null;
    updateUrl = null;
    try {
      const result = await appRpc.request['updater.check']({});
      if (result.error) {
        updateResult = `Check failed: ${result.error}`;
      } else if (result.available) {
        updateResult = `Update available: v${result.version}`;
        updateUrl = result.downloadUrl;
      } else {
        updateResult = `Already up to date (v${appVersion})`;
      }
    } catch (err) {
      updateResult = `Check failed: ${err instanceof Error ? err.message : 'unknown error'}`;
    } finally {
      updateChecking = false;
    }
  }

  async function handleExport() {
    if (!appRpc) return;
    const { settings } = await appRpc.request['settings.getAll']({}).catch(() => ({ settings: {} }));
    const data = JSON.stringify({ version: 1, settings }, null, 2);
    const blob = new Blob([data], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = 'agor-settings.json'; a.click();
    URL.revokeObjectURL(url);
  }

  function handleImport() {
    importError = null;
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json,application/json';
    input.onchange = async () => {
      const file = input.files?.[0];
      if (!file || !appRpc) return;
      try {
        const text = await file.text();
        const parsed = JSON.parse(text);
        const settings: Record<string, string> = parsed.settings ?? parsed;
        if (typeof settings !== 'object') throw new Error('Invalid format');
        for (const [key, value] of Object.entries(settings)) {
          if (typeof value === 'string') {
            await appRpc.request['settings.set']({ key, value });
          }
        }
        // Refresh local state
        await loadSettings();
      } catch (err) {
        importError = err instanceof Error ? err.message : 'Import failed';
      }
    };
    input.click();
  }

  async function loadSettings() {
    if (!appRpc) return;
    const { settings } = await appRpc.request['settings.getAll']({}).catch(() => ({ settings: {} }));
    if (settings['log_level'])          logLevel     = settings['log_level'] as LogLevel;
    if (settings['otlp_endpoint'])      otlpEndpoint = settings['otlp_endpoint'];
    if (settings['relay_urls'])         relayUrls    = settings['relay_urls'];
    if (settings['connection_timeout']) connTimeout  = parseInt(settings['connection_timeout'], 10) || 30;
    if (settings['template_dir'])       templateDir  = settings['template_dir'];
    if (settings['plugin_states']) {
      try {
        const states: Record<string, boolean> = JSON.parse(settings['plugin_states']);
        plugins = plugins.map(p => ({ ...p, enabled: states[p.id] ?? p.enabled }));
      } catch { /* ignore */ }
    }

    // Fetch real version from backend
    try {
      const { version } = await appRpc.request['updater.getVersion']({});
      appVersion = version;
    } catch { /* keep default */ }
  }

  onMount(loadSettings);
</script>

<div class="section">
  <h3 class="sh">Logging</h3>
  <div class="seg">
    {#each LOG_LEVELS as l}
      <button class:active={logLevel === l} onclick={() => setLogLevel(l)}>{l}</button>
    {/each}
  </div>

  <h3 class="sh" style="margin-top: 0.75rem;">Telemetry</h3>
  <div class="field">
    <label class="lbl" for="adv-otlp">OTLP endpoint</label>
    <input id="adv-otlp" class="text-in" value={otlpEndpoint} placeholder="http://localhost:4318"
      onchange={e => setOtlp((e.target as HTMLInputElement).value)} />
  </div>

  <h3 class="sh" style="margin-top: 0.75rem;">Relay</h3>
  <div class="field">
    <label class="lbl" for="adv-relay">Relay URLs (one per line)</label>
    <textarea id="adv-relay" class="prompt" rows="2" value={relayUrls}
      placeholder="wss://relay.example.com:9800"
      onchange={e => setRelayUrls((e.target as HTMLTextAreaElement).value)}></textarea>
  </div>
  <div class="field row">
    <label class="lbl" for="adv-timeout">Connection timeout</label>
    <input id="adv-timeout" class="num-in" type="number" min="5" max="120" value={connTimeout}
      onchange={e => setConnTimeout(parseInt((e.target as HTMLInputElement).value, 10) || 30)} />
    <span class="unit">seconds</span>
  </div>

  <h3 class="sh" style="margin-top: 0.75rem;">Templates</h3>
  <div class="field">
    <label class="lbl" for="adv-tpldir">Template directory</label>
    <input id="adv-tpldir" class="text-in" value={templateDir} placeholder="~/.config/agor/templates/"
      onchange={e => setTemplateDir((e.target as HTMLInputElement).value)} />
    <span class="unit">Where project templates are stored</span>
  </div>

  <h3 class="sh" style="margin-top: 0.75rem;">Plugins</h3>
  <div class="plugin-list">
    {#each plugins as plug}
      <div class="plugin-row">
        <div class="plug-info">
          <span class="plug-name">{plug.name}</span>
          <span class="plug-ver">v{plug.version}</span>
        </div>
        <button class="toggle" class:on={plug.enabled} role="switch"
          aria-checked={plug.enabled} aria-label="Toggle {plug.name}"
          onclick={() => togglePlugin(plug.id)}><span class="thumb"></span></button>
      </div>
    {/each}
    {#if plugins.length === 0}
      <p class="empty">No plugins found in config dir.</p>
    {/if}
  </div>

  <h3 class="sh" style="margin-top: 0.75rem;">Updates</h3>
  <div class="update-row">
    <span class="version-label">v{appVersion}</span>
    <button class="action-btn" onclick={checkForUpdates} disabled={updateChecking}>
      {updateChecking ? 'Checking…' : 'Check for updates'}
    </button>
  </div>
  {#if updateResult}
    <p class="update-result" class:has-update={updateUrl}>{updateResult}</p>
  {/if}
  {#if updateUrl}
    <a class="download-link" href={updateUrl} target="_blank" rel="noopener noreferrer">Download update</a>
  {/if}

  <h3 class="sh" style="margin-top: 0.75rem;">Settings Data</h3>
  <div class="data-row">
    <button class="action-btn" onclick={handleExport}>Export settings</button>
    <button class="action-btn secondary" onclick={handleImport}>Import settings</button>
  </div>
  {#if importError}
    <p class="import-error">{importError}</p>
  {/if}
</div>

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

  .text-in { 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; font-family: var(--ui-font-family); }
  .text-in:focus { outline: none; border-color: var(--ctp-blue); }
  .prompt { padding: 0.375rem 0.5rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem; color: var(--ctp-text); font-size: 0.8rem; font-family: var(--term-font-family, monospace); resize: vertical; line-height: 1.4; }
  .prompt:focus { outline: none; border-color: var(--ctp-blue); }
  .prompt::placeholder { color: var(--ctp-overlay0); }

  .num-in { width: 4rem; 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; appearance: textfield; -moz-appearance: textfield; }
  .num-in::-webkit-inner-spin-button, .num-in::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; }
  .num-in:focus { outline: none; border-color: var(--ctp-blue); }
  .unit { font-size: 0.75rem; color: var(--ctp-overlay0); }

  .seg { display: flex; border-radius: 0.25rem; overflow: hidden; border: 1px solid var(--ctp-surface1); }
  .seg button { flex: 1; padding: 0.25rem 0.375rem; background: var(--ctp-surface0); border: none; color: var(--ctp-overlay1); font-size: 0.7rem; cursor: pointer; font-family: var(--ui-font-family); }
  .seg button:not(:last-child) { border-right: 1px solid var(--ctp-surface1); }
  .seg button:hover { background: var(--ctp-surface1); color: var(--ctp-subtext1); }
  .seg button.active { background: color-mix(in srgb, var(--ctp-blue) 20%, var(--ctp-surface0)); color: var(--ctp-blue); font-weight: 600; }

  .plugin-list { display: flex; flex-direction: column; gap: 0.25rem; }
  .plugin-row { display: flex; align-items: center; justify-content: space-between; padding: 0.375rem 0.5rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 0.25rem; }
  .plug-info { display: flex; align-items: baseline; gap: 0.5rem; }
  .plug-name { font-size: 0.8rem; color: var(--ctp-text); font-weight: 500; }
  .plug-ver { font-size: 0.7rem; color: var(--ctp-overlay0); }
  .empty { font-size: 0.8rem; color: var(--ctp-overlay0); margin: 0; font-style: italic; }

  .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; display: block; }
  .toggle.on .thumb { transform: translateX(0.875rem); }

  .update-row { display: flex; align-items: center; gap: 0.625rem; }
  .version-label { font-size: 0.75rem; color: var(--ctp-overlay1); font-family: var(--term-font-family, monospace); }
  .update-result { font-size: 0.75rem; color: var(--ctp-green); margin: 0.125rem 0 0; }
  .update-result.has-update { color: var(--ctp-peach); }
  .download-link { font-size: 0.75rem; color: var(--ctp-blue); text-decoration: none; margin-top: 0.125rem; }
  .download-link:hover { text-decoration: underline; color: var(--ctp-sapphire); }
  .import-error { font-size: 0.75rem; color: var(--ctp-red); margin: 0.125rem 0 0; }

  .data-row { display: flex; gap: 0.5rem; }

  .action-btn {
    padding: 0.275rem 0.75rem; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1);
    border-radius: 0.25rem; color: var(--ctp-subtext1); font-size: 0.8rem; cursor: pointer; font-family: var(--ui-font-family);
    transition: background 0.12s, color 0.12s;
  }
  .action-btn:hover:not(:disabled) { background: var(--ctp-surface1); color: var(--ctp-text); }
  .action-btn:disabled { opacity: 0.4; cursor: not-allowed; }
  .action-btn.secondary { color: var(--ctp-overlay0); }
</style>
