<script lang="ts">
  import Terminal from './Terminal.svelte';

  // ── Types ────────────────────────────────────────────────────
  type AgentStatus = 'running' | 'idle' | 'stalled';
  type MsgRole = 'user' | 'assistant' | 'tool-call' | 'tool-result';
  type TabId = 'model' | 'docs' | 'files';

  interface AgentMessage {
    id: number;
    role: MsgRole;
    content: string;
  }

  interface Project {
    id: string;
    name: string;
    cwd: string;
    accent: string;
    status: AgentStatus;
    costUsd: number;
    tokens: number;
    messages: AgentMessage[];
  }

  // ── Demo data ────────────────────────────────────────────────
  const PROJECTS: Project[] = [
    {
      id: 'p1',
      name: 'agent-orchestrator',
      cwd: '~/code/ai/agent-orchestrator',
      accent: 'var(--ctp-mauve)',
      status: 'running',
      costUsd: 0.034,
      tokens: 18420,
      messages: [
        { id: 1, role: 'user',        content: 'Add a wake scheduler for Manager agents that wakes them when review queue depth > 3.' },
        { id: 2, role: 'assistant',   content: 'Reading existing wake-scheduler.svelte.ts to understand the 3-strategy pattern...' },
        { id: 3, role: 'tool-call',   content: 'Read("src/lib/stores/wake-scheduler.svelte.ts")' },
        { id: 4, role: 'tool-result', content: '// 312 lines\nexport type WakeStrategy = "persistent" | "on-demand" | "smart";\n...' },
        { id: 5, role: 'assistant',   content: 'Found the WakeSignal enum. I\'ll add ReviewBacklog(0.6) and hook into bttask polling. Writing wake-scorer.ts update now.' },
        { id: 6, role: 'tool-call',   content: 'Edit("src/lib/utils/wake-scorer.ts", old="// signals", new="// signals\n  ReviewBacklog = 0.6,")' },
        { id: 7, role: 'assistant',   content: 'Done. ReviewBacklog signal added at priority 0.6 (between TaskQueuePressure 0.7 and PeriodicFloor 0.1). Run `npm test` to verify 24 scorer tests still pass.' },
      ],
    },
    {
      id: 'p2',
      name: 'quanta-discord-bot',
      cwd: '~/code/quanta/discord-bot',
      accent: 'var(--ctp-sapphire)',
      status: 'idle',
      costUsd: 0.011,
      tokens: 6830,
      messages: [
        { id: 1, role: 'user',        content: 'Why is the QRAG MCP server returning 504s on large semantic search queries?' },
        { id: 2, role: 'assistant',   content: 'Checking the MCP HTTP handler timeout config and Qdrant query path...' },
        { id: 3, role: 'tool-call',   content: 'Read("src/mcp/server.ts", offset=120, limit=40)' },
        { id: 4, role: 'tool-result', content: 'const QUERY_TIMEOUT_MS = 5000; // default\n...' },
        { id: 5, role: 'assistant',   content: 'Found it. The MCP handler has a hardcoded 5s timeout but Qdrant HNSW search on 500k vectors takes 6–9s at ef=256. Two options:\n1. Raise timeout to 15s (quick fix)\n2. Lower ef to 128 for faster approximate search (~3s, slight recall drop)\n\nRecommend option 2 for latency-sensitive bot responses.' },
        { id: 6, role: 'user',        content: 'Go with option 2.' },
        { id: 7, role: 'assistant',   content: 'Updated `ef_searching: 128` in qdrant-config.ts and raised timeout to 8s as safety margin. Restarted service on port 9320.' },
      ],
    },
  ];

  // ── Reactive state ───────────────────────────────────────────
  let activeTab = $state<Record<string, TabId>>({ p1: 'model', p2: 'model' });
  let settingsOpen = $state(false);

  // ── Derived status bar aggregates ───────────────────────────
  let runningCount = $derived(PROJECTS.filter(p => p.status === 'running').length);
  let idleCount    = $derived(PROJECTS.filter(p => p.status === 'idle').length);
  let totalCost    = $derived(PROJECTS.reduce((s, p) => s + p.costUsd, 0));
  let totalTokens  = $derived(PROJECTS.reduce((s, p) => s + p.tokens, 0));

  function setTab(projectId: string, tab: TabId) {
    activeTab = { ...activeTab, [projectId]: tab };
  }

  // Blink state — JS timer toggles class, NO CSS animation (0% CPU)
  let blinkVisible = $state(true);
  $effect(() => {
    const id = setInterval(() => { blinkVisible = !blinkVisible; }, 500);
    return () => clearInterval(id);
  });

  function fmtTokens(n: number): string {
    return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);
  }

  function fmtCost(n: number): string {
    return `$${n.toFixed(3)}`;
  }
</script>

<div class="app-shell">
  <!-- ── Sidebar icon rail ──────────────────────────────────── -->
  <aside class="sidebar" role="navigation" aria-label="Primary navigation">
    <div class="sidebar-spacer"></div>
    <button
      class="sidebar-icon"
      class:active={settingsOpen}
      onclick={() => settingsOpen = !settingsOpen}
      aria-label="Settings"
      title="Settings"
    >
      <!-- gear icon -->
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <circle cx="12" cy="12" r="3"/>
        <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
      </svg>
    </button>
  </aside>

  <!-- ── Main workspace ───────────────────────────────────────── -->
  <main class="workspace">
    <div class="project-grid">
      {#each PROJECTS as project (project.id)}
        <article
          class="project-card"
          style="--accent: {project.accent}"
          aria-label="Project: {project.name}"
        >
          <!-- Project header -->
          <header class="project-header">
            <!-- Status dot — wgpu surface placeholder -->
            <div class="status-dot-wrap" aria-label="Status: {project.status}">
              <!--
                Future: replace inner div with <electrobun-wgpu id="wgpu-surface-{project.id}">
                for GPU-rendered animation. CSS pulse is the WebView fallback.
              -->
              <div
                class="status-dot {project.status}"
                class:blink-off={project.status === 'running' && !blinkVisible}
                role="img"
                aria-label="{project.status}"
              ></div>
            </div>

            <span class="project-name">{project.name}</span>
            <span class="project-cwd" title={project.cwd}>{project.cwd}</span>
          </header>

          <!-- Tab bar -->
          <div class="tab-bar" role="tablist" aria-label="{project.name} tabs">
            {#each (['model', 'docs', 'files'] as TabId[]) as tab}
              <button
                class="tab-btn"
                class:active={activeTab[project.id] === tab}
                role="tab"
                aria-selected={activeTab[project.id] === tab}
                aria-controls="tabpanel-{project.id}-{tab}"
                onclick={() => setTab(project.id, tab)}
              >
                {tab.charAt(0).toUpperCase() + tab.slice(1)}
              </button>
            {/each}
          </div>

          <!-- Tab content -->
          <div class="tab-content">
            <!-- Model tab: agent messages -->
            <div
              id="tabpanel-{project.id}-model"
              class="tab-pane"
              class:active={activeTab[project.id] === 'model'}
              role="tabpanel"
              aria-label="Model"
            >
              <div class="agent-messages">
                {#each project.messages as msg (msg.id)}
                  <div class="msg">
                    <span class="msg-role {msg.role.split('-')[0]}">{msg.role}</span>
                    <div
                      class="msg-body"
                      class:tool-call={msg.role === 'tool-call'}
                      class:tool-result={msg.role === 'tool-result'}
                    >{msg.content}</div>
                  </div>
                {/each}
              </div>
              <!-- Terminal section -->
              <div class="terminal-section">
                <Terminal />
              </div>
            </div>

            <!-- Docs tab placeholder -->
            <div
              id="tabpanel-{project.id}-docs"
              class="tab-pane"
              class:active={activeTab[project.id] === 'docs'}
              role="tabpanel"
              aria-label="Docs"
            >
              <div class="placeholder-pane">No markdown files open</div>
            </div>

            <!-- Files tab placeholder -->
            <div
              id="tabpanel-{project.id}-files"
              class="tab-pane"
              class:active={activeTab[project.id] === 'files'}
              role="tabpanel"
              aria-label="Files"
            >
              <div class="placeholder-pane">File browser — coming soon</div>
            </div>
          </div>
        </article>
      {/each}
    </div>
  </main>
</div>

<!-- ── Status bar ─────────────────────────────────────────────── -->
<footer class="status-bar" role="status" aria-live="polite" aria-label="System status">
  {#if runningCount > 0}
    <span class="status-segment">
      <span class="status-dot-sm green" aria-hidden="true"></span>
      <span class="status-value">{runningCount}</span>
      <span>running</span>
    </span>
  {/if}
  {#if idleCount > 0}
    <span class="status-segment">
      <span class="status-dot-sm gray" aria-hidden="true"></span>
      <span class="status-value">{idleCount}</span>
      <span>idle</span>
    </span>
  {/if}
  <span class="status-bar-spacer"></span>
  <span class="status-segment" title="Total tokens used">
    <span>tokens</span>
    <span class="status-value">{fmtTokens(totalTokens)}</span>
  </span>
  <span class="status-segment" title="Total session cost">
    <span>cost</span>
    <span class="status-value">{fmtCost(totalCost)}</span>
  </span>
</footer>

<style>
  /* Component-scoped overrides only — base styles live in app.css */
  :global(body) {
    overflow: hidden;
  }

  :global(#app) {
    display: flex;
    flex-direction: column;
    height: 100vh;
  }

  .app-shell {
    flex: 1;
    min-height: 0;
  }
</style>
