<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, FILTERS, TASK_EVENTS, heading, type Bucket } from '$lib/tasks'
  import { Button } from '$lib/components/ui/button'
  import DataTable from '$lib/components/data-table/DataTable.svelte'
  import type { DataTableColumn } from '$lib/components/data-table/types'
  import StatusDotRenderer from '$lib/components/data-table/renderers/StatusDotRenderer.svelte'
  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()

    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()
    }
  })

  const columns: DataTableColumn<Session>[] = [
    {
      key: '_status',
      header: 'Status',
      render: StatusDotRenderer,
      sortable: true,
      accessor: (s) => bucket(s),
      width: '140px'
    },
    { key: '_heading', header: 'Task', sortable: true, accessor: heading, truncate: true },
    {
      key: 'summary',
      header: 'Summary',
      accessor: (s) => s.summary || '—',
      truncate: true,
      headerClass: 'hidden md:table-cell',
      class: 'hidden md:table-cell'
    },
    {
      key: 'last_active_at',
      header: 'Last active',
      render: 'relative-time',
      sortable: true,
      width: '112px',
      align: 'right'
    }
  ]

  const emptyMessage = $derived(
    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.`
  )
</script>

<div class="relative flex h-full flex-col gap-3 overflow-hidden p-2">
  <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="border px-2.5 py-1 text-xs transition-colors {filter === f.id
          ? 'border-foreground bg-foreground text-background'
          : 'border-border text-muted-foreground hover:border-foreground hover:text-foreground'}"
      >
        {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-hidden rounded-xl border bg-card/70 backdrop-blur"
  >
    <DataTable {columns} data={visible} {emptyMessage} bordered={false} onRowClick={openTask} />
  </div>
</div>
