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

  interface CatalogPlugin {
    id: string;
    name: string;
    version: string;
    description: string;
    author: string;
    icon: string;
    tags: string[];
    free: boolean;
  }

  const DEMO_CATALOG: CatalogPlugin[] = [
    { id: 'secret-scanner',        name: 'Secret Scanner',        version: '1.0.0', author: 'Quanta',   icon: '🔍', tags: ['security'],   free: true,  description: 'Detects exposed secrets and API keys in agent sessions before they leak.' },
    { id: 'productivity-insights', name: 'Productivity Insights', version: '1.1.0', author: 'Quanta',   icon: '📊', tags: ['analytics'],  free: true,  description: 'Session analytics, cost breakdowns, and agent efficiency metrics.' },
    { id: 'git-guardian',          name: 'Git Guardian',          version: '0.9.2', author: 'Community',icon: '🛡️', tags: ['security', 'git'], free: true, description: 'Enforces branch policies and blocks commits to protected branches.' },
    { id: 'context-compressor',    name: 'Context Compressor',    version: '1.0.3', author: 'Quanta',   icon: '🗜️', tags: ['performance'], free: true,  description: 'Intelligently compresses context windows to reduce token usage.' },
    { id: 'slack-notifier',        name: 'Slack Notifier',        version: '0.5.0', author: 'Community',icon: '💬', tags: ['notifications'], free: true, description: 'Sends agent completion and error notifications to Slack channels.' },
    { id: 'multi-model-router',    name: 'Multi-Model Router',    version: '1.2.0', author: 'Quanta',   icon: '🔀', tags: ['routing', 'ai'], free: true, description: 'Routes tasks to the cheapest capable model based on complexity scoring.' },
    { id: 'audit-exporter',        name: 'Audit Exporter',        version: '0.8.1', author: 'Community',icon: '📋', tags: ['compliance'],  free: true,  description: 'Exports audit logs to SIEM systems (Splunk, Datadog, CloudWatch).' },
    { id: 'test-runner-bridge',    name: 'Test Runner Bridge',    version: '1.0.0', author: 'Quanta',   icon: '🧪', tags: ['testing'],     free: true,  description: 'Runs test suites on agent-modified code and surfaces failures inline.' },
  ];

  type Tab = 'browse' | 'installed';
  let activeTab   = $state<Tab>('browse');
  let searchQuery = $state('');
  let installed   = $state<Set<string>>(new Set());
  let installing  = $state<Set<string>>(new Set());

  let filtered = $derived(
    DEMO_CATALOG.filter(p => {
      if (activeTab === 'installed' && !installed.has(p.id)) return false;
      if (!searchQuery) return true;
      const q = searchQuery.toLowerCase();
      return p.name.toLowerCase().includes(q)
        || p.description.toLowerCase().includes(q)
        || p.tags.some(t => t.includes(q));
    })
  );

  async function installPlugin(id: string) {
    installing = new Set([...installing, id]);
    const states: Record<string, boolean> = {};
    for (const pid of installed) states[pid] = true;
    states[id] = true;
    await appRpc?.request['settings.set']({ key: 'marketplace_installed', value: JSON.stringify(states) }).catch(console.error);
    installed = new Set([...installed, id]);
    installing = new Set([...installing].filter(x => x !== id));
  }

  async function uninstallPlugin(id: string) {
    installed = new Set([...installed].filter(x => x !== id));
    const states: Record<string, boolean> = {};
    for (const pid of installed) states[pid] = true;
    await appRpc?.request['settings.set']({ key: 'marketplace_installed', value: JSON.stringify(states) }).catch(console.error);
  }

  onMount(async () => {
    if (!appRpc) return;
    const res = await appRpc.request['settings.get']({ key: 'marketplace_installed' }).catch(() => ({ value: null }));
    if (res.value) {
      try {
        const states: Record<string, boolean> = JSON.parse(res.value);
        installed = new Set(Object.entries(states).filter(([, v]) => v).map(([k]) => k));
      } catch { /* ignore */ }
    }
  });
</script>

<div class="marketplace">
  <!-- Tab bar -->
  <div class="tab-bar">
    <button class="tab" class:active={activeTab === 'browse'} onclick={() => activeTab = 'browse'}>Browse</button>
    <button class="tab" class:active={activeTab === 'installed'} onclick={() => activeTab = 'installed'}>
      Installed {installed.size > 0 ? `(${installed.size})` : ''}
    </button>
    <div class="search-wrap">
      <input class="search-in" bind:value={searchQuery} placeholder="Search plugins…" aria-label="Search marketplace" />
      {#if searchQuery}
        <button class="search-clear" onclick={() => searchQuery = ''} aria-label="Clear search">✕</button>
      {/if}
    </div>
  </div>

  <!-- Plugin grid -->
  <div class="plugin-grid">
    {#each filtered as plugin}
      <div class="plugin-card">
        <div class="card-top">
          <span class="plugin-icon" aria-hidden="true">{plugin.icon}</span>
          <div class="plugin-meta">
            <span class="plugin-name">{plugin.name}</span>
            <span class="plugin-author">{plugin.author} · v{plugin.version}</span>
          </div>
          {#if installed.has(plugin.id)}
            <button class="uninstall-btn" onclick={() => uninstallPlugin(plugin.id)} aria-label="Uninstall {plugin.name}">
              Installed ✓
            </button>
          {:else}
            <button class="install-btn"
              disabled={installing.has(plugin.id)}
              onclick={() => installPlugin(plugin.id)}
              aria-label="Install {plugin.name}"
            >
              {installing.has(plugin.id) ? '…' : 'Install'}
            </button>
          {/if}
        </div>
        <p class="plugin-desc">{plugin.description}</p>
        <div class="tag-row">
          {#each plugin.tags as tag}
            <span class="tag">{tag}</span>
          {/each}
          {#if plugin.free}
            <span class="tag free">free</span>
          {/if}
        </div>
      </div>
    {/each}
    {#if filtered.length === 0}
      <p class="empty-hint">
        {activeTab === 'installed' ? 'No plugins installed yet.' : 'No plugins match your search.'}
      </p>
    {/if}
  </div>
</div>

<style>
  .marketplace { display: flex; flex-direction: column; gap: 0.625rem; }

  .tab-bar { display: flex; align-items: center; gap: 0.25rem; border-bottom: 1px solid var(--ctp-surface1); padding-bottom: 0.375rem; }

  .tab { padding: 0.25rem 0.625rem; background: transparent; border: none; border-radius: 0.25rem; color: var(--ctp-subtext0); font-size: 0.8125rem; cursor: pointer; font-family: var(--ui-font-family); white-space: nowrap; }
  .tab:hover { color: var(--ctp-text); background: var(--ctp-surface0); }
  .tab.active { color: var(--ctp-mauve); background: color-mix(in srgb, var(--ctp-mauve) 10%, var(--ctp-surface0)); font-weight: 600; }

  .search-wrap { position: relative; flex: 1; display: flex; align-items: center; }
  .search-in {
    width: 100%; padding: 0.25rem 1.75rem 0.25rem 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(--ui-font-family);
  }
  .search-in:focus { outline: none; border-color: var(--ctp-blue); }
  .search-in::placeholder { color: var(--ctp-overlay0); }
  .search-clear { position: absolute; right: 0.375rem; background: none; border: none; color: var(--ctp-overlay0); cursor: pointer; font-size: 0.75rem; padding: 0.125rem; }
  .search-clear:hover { color: var(--ctp-text); }

  .plugin-grid { display: flex; flex-direction: column; gap: 0.5rem; }

  .plugin-card {
    background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1);
    border-radius: 0.375rem; padding: 0.625rem;
    transition: border-color 0.12s;
  }
  .plugin-card:hover { border-color: var(--ctp-surface2); }

  .card-top { display: flex; align-items: flex-start; gap: 0.5rem; margin-bottom: 0.375rem; }

  .plugin-icon { font-size: 1.5rem; flex-shrink: 0; line-height: 1; margin-top: 0.1rem; }

  .plugin-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.125rem; }
  .plugin-name { font-size: 0.875rem; font-weight: 600; color: var(--ctp-text); }
  .plugin-author { font-size: 0.7rem; color: var(--ctp-overlay1); }

  .install-btn {
    padding: 0.25rem 0.75rem; background: var(--ctp-blue); border: none; border-radius: 0.25rem;
    color: var(--ctp-base); font-size: 0.75rem; font-weight: 600; cursor: pointer;
    font-family: var(--ui-font-family); flex-shrink: 0; white-space: nowrap;
  }
  .install-btn:hover:not(:disabled) { filter: brightness(1.1); }
  .install-btn:disabled { opacity: 0.5; cursor: not-allowed; }

  .uninstall-btn {
    padding: 0.25rem 0.75rem; background: color-mix(in srgb, var(--ctp-green) 12%, var(--ctp-surface0));
    border: 1px solid var(--ctp-green); border-radius: 0.25rem; color: var(--ctp-green);
    font-size: 0.75rem; font-weight: 600; cursor: pointer; font-family: var(--ui-font-family);
    flex-shrink: 0; white-space: nowrap;
  }
  .uninstall-btn:hover {
    background: color-mix(in srgb, var(--ctp-red) 12%, var(--ctp-surface0));
    border-color: var(--ctp-red); color: var(--ctp-red);
  }

  .plugin-desc { font-size: 0.775rem; color: var(--ctp-subtext0); margin: 0 0 0.375rem; line-height: 1.4; }

  .tag-row { display: flex; flex-wrap: wrap; gap: 0.25rem; }
  .tag {
    padding: 0.1rem 0.4rem; background: color-mix(in srgb, var(--ctp-mauve) 10%, transparent);
    color: var(--ctp-mauve); border-radius: 0.75rem; font-size: 0.65rem; font-weight: 500;
  }
  .tag.free {
    background: color-mix(in srgb, var(--ctp-green) 10%, transparent); color: var(--ctp-green);
  }

  .empty-hint { font-size: 0.8rem; color: var(--ctp-overlay0); text-align: center; padding: 1.5rem 0; margin: 0; font-style: italic; }
</style>
