<script lang="ts">
  import { onMount } from 'svelte'
  import { sessions, loadSessions } from '$lib/stores/chat'
  import { openTaskWindow, openNewTaskWindow } from '$lib/stores/windows'
  import { liveEvents, subscribeEvents } from '$lib/stores/events'
  import { bucket, statusStyle, FILTERS, TASK_EVENTS, heading, type Bucket } from '$lib/tasks'
  import { relativeTime } from '$lib/utils'
  import GraphBackground from '$lib/components/GraphBackground.svelte'
  import { Button } from '$lib/components/ui/button'
  import PlusIcon from '@lucide/svelte/icons/plus'
  import type { Session } from '$lib/api'

  // ── Task board ──────────────────────────────────────────────────────────
  let filter = $state<'all' | Bucket>('all')

  const counts = $derived.by(() => {
    const c: Record<string, number> = { all: $sessions.length, running: 0, input: 0, done: 0, failed: 0 }
    for (const s of $sessions) c[bucket(s)]++
    return c
  })
  const visible = $derived(
    filter === 'all' ? $sessions : $sessions.filter((s) => bucket(s) === filter)
  )

  function openTask(s: Session) {
    openTaskWindow(s.id, heading(s))
  }

  onMount(() => {
    loadSessions()
    const unsubStream = subscribeEvents()

    // Refetch the board when a task's lifecycle changes anywhere. Scan all
    // events newer than the last seen (entity.touched fires constantly and
    // buries task.status); debounce a burst into one refetch.
    let lastSeenId = 0
    let refreshTimer: ReturnType<typeof setTimeout> | null = null
    const unsub = liveEvents.subscribe((evs) => {
      if (evs.length === 0) return
      const maxId = evs[0].id
      if (maxId <= lastSeenId) return
      const relevant = evs.some((e) => e.id > lastSeenId && TASK_EVENTS.has(e.type))
      lastSeenId = maxId
      if (relevant) {
        if (refreshTimer) clearTimeout(refreshTimer)
        refreshTimer = setTimeout(() => loadSessions(), 400)
      }
    })

    return () => {
      unsub()
      unsubStream()
    }
  })
</script>

<div class="relative flex h-full flex-col gap-3 overflow-hidden p-4">
  <GraphBackground />

  <div class="relative z-10 flex flex-wrap items-center gap-1.5">
    {#each FILTERS as f}
      <button
        type="button"
        onclick={() => (filter = f.id)}
        class="rounded-full border px-2.5 py-1 text-xs transition-colors {filter === f.id
          ? 'border-primary bg-primary/10 text-foreground'
          : 'border-border bg-card/60 text-muted-foreground backdrop-blur hover:bg-muted/50'}"
      >
        {f.label}
        <span class="ml-1 opacity-60">{counts[f.id] ?? 0}</span>
      </button>
    {/each}
    <div class="flex-1"></div>
    <Button size="sm" class="gap-1.5" onclick={openNewTaskWindow}>
      <PlusIcon class="size-4" />
      New task
    </Button>
  </div>

  <div class="relative z-10 min-h-0 flex-1 overflow-auto rounded-xl border bg-card/70 backdrop-blur">
    {#if visible.length === 0}
      <div class="flex flex-col items-center gap-2 px-4 py-16 text-center">
        <p class="max-w-sm text-sm text-muted-foreground">
          {filter === 'all'
            ? 'No tasks yet. Start one and Nomos will plan it, execute it, and report the outcome.'
            : `No ${FILTERS.find((f) => f.id === filter)?.label.toLowerCase()} tasks.`}
        </p>
      </div>
    {:else}
      <table class="w-full text-sm">
        <thead>
          <tr class="border-b text-left text-xs text-muted-foreground">
            <th class="w-36 px-4 py-2 font-medium">Status</th>
            <th class="px-4 py-2 font-medium">Task</th>
            <th class="hidden px-4 py-2 font-medium md:table-cell">Summary</th>
            <th class="w-28 px-4 py-2 text-right font-medium">Last active</th>
          </tr>
        </thead>
        <tbody>
          {#each visible as s (s.id)}
            {@const st = statusStyle(s)}
            <tr
              class="cursor-pointer border-b last:border-0 transition-colors hover:bg-muted/40"
              onclick={() => openTask(s)}
            >
              <td class="px-4 py-2.5">
                <span class="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
                  <span class="size-2 rounded-full {st.dot} {st.pulse ? 'animate-pulse' : ''}"></span>
                  {st.label}
                </span>
              </td>
              <td class="max-w-0 px-4 py-2.5">
                <span class="line-clamp-1 font-medium">{heading(s)}</span>
              </td>
              <td class="hidden max-w-0 px-4 py-2.5 md:table-cell">
                <span class="line-clamp-1 text-xs text-muted-foreground">{s.summary || '—'}</span>
              </td>
              <td class="whitespace-nowrap px-4 py-2.5 text-right text-[11px] text-muted-foreground">
                {relativeTime(s.last_active_at)}
              </td>
            </tr>
          {/each}
        </tbody>
      </table>
    {/if}
  </div>
</div>
