<script lang="ts">
  import { onMount } from 'svelte'
  import { fetchDashboardSummary, type DashboardSummary } from '$lib/api'
  import { sessions, loadSessions, loadSessionMessages, newChat, sendMessage } from '$lib/stores/chat'
  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 { Textarea } from '$lib/components/ui/textarea'
  import { Button } from '$lib/components/ui/button'
  import ArrowUpIcon from '@lucide/svelte/icons/arrow-up'
  import CircleCheckIcon from '@lucide/svelte/icons/circle-check'
  import TriangleAlertIcon from '@lucide/svelte/icons/triangle-alert'

  // ── Dashboard metrics (ported from the old Overview cards) ──────────────
  let summary = $state<DashboardSummary | null>(null)

  async function loadSummary() {
    summary = await fetchDashboardSummary()
  }

  const totalEntities = $derived(
    summary ? Object.values(summary.entities_by_type).reduce((a, b) => a + b, 0) : 0
  )
  const entityTypeCount = $derived(summary ? Object.keys(summary.entities_by_type).length : 0)
  const totalMonitored = $derived(
    summary
      ? summary.health.healthy + summary.health.degraded + summary.health.down + summary.health.unknown
      : 0
  )
  const healthTone = $derived(
    !summary ? 'ok' : summary.health.down > 0 ? 'down' : summary.health.degraded > 0 ? 'degraded' : 'ok'
  )
  const totalSignals = $derived(
    summary ? Object.values(summary.signals_by_severity).reduce((a, b) => a + b, 0) : 0
  )
  const worstSeverity = $derived(
    summary?.signals_by_severity.critical
      ? 'critical'
      : summary?.signals_by_severity.warning
        ? 'warning'
        : 'none'
  )

  // ── 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(id: string) {
    loadSessionMessages(id)
    location.hash = '#/chat'
  }

  // ── New task entry ──────────────────────────────────────────────────────
  let input = $state('')
  function submit() {
    const text = input.trim()
    if (!text) return
    input = ''
    newChat()
    sendMessage(text)
    location.hash = '#/chat'
  }
  function handleKeydown(e: KeyboardEvent) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      submit()
    }
  }

  onMount(() => {
    loadSummary()
    loadSessions()
    const unsubStream = subscribeEvents()
    const summaryTimer = setInterval(loadSummary, 15000)

    // 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()
      clearInterval(summaryTimer)
    }
  })
</script>

<div class="relative h-full overflow-hidden">
  <GraphBackground />

  <div class="relative z-10 h-full overflow-y-auto">
    <!-- Hero: fills the viewport. The input is pinned to true vertical center via the
         grid's middle 1fr row; the metrics strip and scroll hint sit in the auto rows
         above/below without shifting it off-center. Scrolling lifts the whole hero to
         reveal the table. -->
    <section class="grid min-h-full grid-rows-[auto_1fr_auto] gap-6 px-4 py-16">
      <!-- Metrics strip -->
      <div class="flex flex-wrap items-center justify-center gap-2 text-xs">
        <div class="flex items-center gap-1.5 rounded-full border bg-card/60 px-3 py-1.5 backdrop-blur">
          <span class="text-muted-foreground">Entities</span>
          <span class="font-semibold tabular-nums">{totalEntities}</span>
          {#if entityTypeCount}<span class="text-muted-foreground">· {entityTypeCount} types</span>{/if}
        </div>
        <div class="flex items-center gap-1.5 rounded-full border bg-card/60 px-3 py-1.5 backdrop-blur">
          <span
            class="size-2 rounded-full {healthTone === 'ok' ? 'bg-success' : healthTone === 'degraded' ? 'bg-warning' : 'bg-destructive'}"
          ></span>
          <span class="text-muted-foreground">Health</span>
          <span class="font-semibold tabular-nums">{summary?.health.healthy ?? 0} / {totalMonitored}</span>
        </div>
        <button
          type="button"
          onclick={() => (location.hash = '#/signals')}
          class="flex items-center gap-1.5 rounded-full border bg-card/60 px-3 py-1.5 backdrop-blur transition-colors hover:border-primary/50"
        >
          {#if worstSeverity === 'critical'}
            <TriangleAlertIcon class="size-3.5 text-destructive" />
          {:else if worstSeverity === 'warning'}
            <TriangleAlertIcon class="size-3.5 text-warning" />
          {:else}
            <CircleCheckIcon class="size-3.5 text-success" />
          {/if}
          <span class="text-muted-foreground">Signals</span>
          <span class="font-semibold tabular-nums">{totalSignals}</span>
        </button>
        <button
          type="button"
          onclick={() => (location.hash = '#/ops')}
          class="flex items-center gap-1.5 rounded-full border bg-card/60 px-3 py-1.5 backdrop-blur transition-colors hover:border-primary/50"
        >
          <span class="text-muted-foreground">Approvals</span>
          <span class="font-semibold tabular-nums {summary?.approvals_pending ? 'text-destructive' : ''}"
            >{summary?.approvals_pending ?? 0}</span
          >
        </button>
      </div>

      <!-- New task entry: centered in the middle (1fr) row -->
      <div class="flex items-center justify-center">
      <div class="w-full max-w-2xl text-center">
        <h1 class="mb-1 text-2xl font-semibold tracking-tight">What should Nomos do?</h1>
        <p class="mb-4 text-sm text-muted-foreground">
          Describe a goal — Nomos will plan it, execute it, and report the outcome.
        </p>
        <form
          class="relative rounded-2xl border bg-card/70 shadow-lg backdrop-blur focus-within:border-primary/60"
          onsubmit={(e) => {
            e.preventDefault()
            submit()
          }}
        >
          <Textarea
            bind:value={input}
            onkeydown={handleKeydown}
            placeholder="e.g. Roll the staging database back to last night's snapshot and verify the app is healthy…"
            rows={3}
            class="max-h-52 min-h-24 resize-none border-0 bg-transparent px-4 py-3.5 text-base shadow-none focus-visible:ring-0"
          />
          <div class="flex items-center justify-between px-3 pb-3">
            <span class="text-[11px] text-muted-foreground">Enter to start · Shift+Enter for newline</span>
            <Button type="submit" size="icon" disabled={!input.trim()} aria-label="Start task">
              <ArrowUpIcon />
            </Button>
          </div>
        </form>
      </div>
      </div>

      <span class="justify-self-center text-[11px] text-muted-foreground/70">Scroll to see all tasks ↓</span>
    </section>

    <!-- Task table -->
    <section class="mx-auto w-full max-w-5xl px-4 pb-16">
      <div class="rounded-xl border bg-card/70 backdrop-blur">
        <div class="flex flex-wrap items-center gap-1.5 border-b p-3">
          {#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 text-muted-foreground hover:bg-muted/50'}"
            >
              {f.label}
              <span class="ml-1 opacity-60">{counts[f.id] ?? 0}</span>
            </button>
          {/each}
        </div>

        {#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 above and Nomos will plan it, execute it, and report the outcome.'
                : `No ${FILTERS.find((f) => f.id === filter)?.label.toLowerCase()} tasks.`}
            </p>
          </div>
        {:else}
          <div class="overflow-x-auto">
            <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.id)}
                  >
                    <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>
          </div>
        {/if}
      </div>
    </section>
  </div>
</div>
