<script lang="ts">
  // The reader pane's resting state — what you see every time the app opens
  // and nothing is selected yet.
  //
  // This used to be the sentence "Select a note, or create a new one."
  // centred in an otherwise empty 56%-width pane: the single most-seen screen
  // in the app doing no work at all. It's now the landing view, and it also
  // restores the collection-level numbers the wiki redesign dropped (the old
  // stats-only Knowledge page led with them, and they were the one thing that
  // page did well — "the system is getting smarter" is only visible in
  // aggregate).
  //
  // Every figure is derived from the `items` array the parent already loaded
  // for the tree, so this panel costs no extra request.
  import type { KnowledgeListItem } from '$lib/api'
  import { kindMeta, isAgentAuthored } from './kinds'
  import { relativeTime } from '$lib/utils'
  import BotIcon from '@lucide/svelte/icons/bot'
  import SparklesIcon from '@lucide/svelte/icons/sparkles'
  import ClockIcon from '@lucide/svelte/icons/clock'
  import HashIcon from '@lucide/svelte/icons/hash'
  import PlusIcon from '@lucide/svelte/icons/plus'
  import { Button } from '$lib/components/ui/button'

  let {
    items,
    onSelect,
    onNew
  }: {
    items: KnowledgeListItem[]
    onSelect: (slug: string) => void
    onNew: () => void
  } = $props()

  const WEEK_MS = 7 * 24 * 60 * 60 * 1000

  // Postgres renders timestamptz as "2026-07-26 10:50:53.475644+00" — a space
  // instead of ISO-8601's 'T', and a bare two-digit offset. V8 happens to
  // accept that verbatim, but Safari's parser requires the 'T' AND an offset
  // of 'Z' or ±HH:MM, so both have to be normalised together: swapping only
  // the separator yields "…475644+00", which is invalid ISO and parses to NaN
  // *everywhere* — strictly worse than leaving the string alone.
  function parseTimestamp(raw: string): number {
    return Date.parse(raw.replace(' ', 'T').replace(/([+-]\d{2})$/, '$1:00'))
  }

  const stats = $derived.by(() => {
    const now = Date.now()
    let agent = 0
    let lastWeek = 0
    const byKind = new Map<string, number>()
    const tagCounts = new Map<string, number>()

    for (const it of items) {
      if (isAgentAuthored(it.edited_by)) agent++
      const ts = parseTimestamp(it.updated_at)
      if (!Number.isNaN(ts) && now - ts < WEEK_MS) lastWeek++
      byKind.set(it.kind, (byKind.get(it.kind) ?? 0) + 1)
      for (const t of it.tags) tagCounts.set(t, (tagCounts.get(t) ?? 0) + 1)
    }

    return {
      total: items.length,
      agent,
      lastWeek,
      byKind,
      topTags: [...tagCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10)
    }
  })

  // Share of the collection the agent wrote — the "is this thing actually
  // learning" number, and the only ratio here worth a meter rather than
  // another tile.
  const agentShare = $derived(stats.total === 0 ? 0 : Math.round((stats.agent / stats.total) * 100))

  const recent = $derived(
    [...items].sort((a, b) => b.updated_at.localeCompare(a.updated_at)).slice(0, 6)
  )

  // Kinds in a fixed order so the row doesn't reshuffle as counts change.
  const KIND_ORDER = ['runbook', 'investigation', 'document'] as const
</script>

<div class="mx-auto flex h-full w-full max-w-2xl flex-col gap-7 overflow-y-auto px-1 py-6">
  {#if stats.total === 0}
    <!-- Genuinely empty collection (not a failed load — the parent handles
         that case before rendering this component). -->
    <div class="flex flex-1 flex-col items-center justify-center gap-3 text-center">
      <h2 class="text-lg font-semibold">Nothing here yet</h2>
      <p class="max-w-sm text-sm text-muted-foreground">
        The knowledge base is empty. Write the first note, or let Nomos record what it learns as it
        works.
      </p>
      <Button size="sm" class="gap-1.5" onclick={onNew}>
        <PlusIcon class="size-3.5" /> New note
      </Button>
    </div>
  {:else}
    <!-- Hero: the one number the view leads with. Sans, not the Inknut
         heading face — a serif at display size reads as decoration rather
         than data. Proportional figures (no tabular-nums): this is a
         standalone value, not a column that has to align. -->
    <div>
      <h2 class="text-sm font-medium tracking-wide text-muted-foreground uppercase">
        Knowledge base
      </h2>
      <div class="mt-1 flex items-baseline gap-2.5">
        <span class="font-sans text-5xl leading-none font-semibold">{stats.total}</span>
        <span class="text-sm text-muted-foreground">notes</span>
      </div>
    </div>

    <!-- KPI row. Hairline dividers rather than boxed cards: at four items the
         boxes were doing more visual work than the numbers inside them. -->
    <div class="grid grid-cols-2 gap-px overflow-hidden rounded-lg bg-border/60 sm:grid-cols-4">
      {#each KIND_ORDER as k (k)}
        {@const meta = kindMeta(k)}
        {@const Icon = meta.icon}
        <div class="flex flex-col gap-1 bg-card px-3 py-2.5">
          <span class="flex items-center gap-1.5 text-[11px] text-muted-foreground">
            <Icon class="size-3.5" />
            {meta.plural}
          </span>
          <span class="text-xl font-semibold">{stats.byKind.get(k) ?? 0}</span>
        </div>
      {/each}
      <div class="flex flex-col gap-1 bg-card px-3 py-2.5">
        <span class="flex items-center gap-1.5 text-[11px] text-muted-foreground">
          <SparklesIcon class="size-3.5" /> this week
        </span>
        <span class="text-xl font-semibold">{stats.lastWeek}</span>
      </div>
    </div>

    <!-- Meter: one ratio, one hue. Track is a lighter step of the fill's own
         ramp so the whole bar reads as a single scale. -->
    <div class="flex flex-col gap-1.5">
      <div class="flex items-baseline justify-between text-xs">
        <span class="flex items-center gap-1.5 text-muted-foreground">
          <BotIcon class="size-3.5" /> Written by Nomos
        </span>
        <span class="text-muted-foreground">
          <span class="font-semibold text-foreground">{stats.agent}</span> of {stats.total} · {agentShare}%
        </span>
      </div>
      <div
        class="h-1.5 overflow-hidden rounded-full bg-primary/15"
        role="meter"
        aria-valuenow={agentShare}
        aria-valuemin={0}
        aria-valuemax={100}
        aria-label="Share of notes written by Nomos"
      >
        <div class="h-full rounded-full bg-primary" style="width: {agentShare}%"></div>
      </div>
    </div>

    <div class="flex flex-col gap-2">
      <h3 class="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
        <ClockIcon class="size-3.5" /> Recently updated
      </h3>
      <div class="flex flex-col">
        {#each recent as it (it.slug)}
          {@const Icon = kindMeta(it.kind).icon}
          <button
            type="button"
            class="group flex items-center gap-2.5 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted/50"
            onclick={() => onSelect(it.slug)}
          >
            <Icon class="size-3.5 shrink-0 text-muted-foreground" />
            <span class="min-w-0 flex-1 truncate text-sm group-hover:text-primary">{it.title}</span>
            {#if isAgentAuthored(it.edited_by)}
              <BotIcon class="size-3 shrink-0 text-muted-foreground" />
            {/if}
            <span class="shrink-0 text-[11px] text-muted-foreground"
              >{relativeTime(it.updated_at)}</span
            >
          </button>
        {/each}
      </div>
    </div>

    {#if stats.topTags.length > 0}
      <div class="flex flex-col gap-2">
        <h3 class="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
          <HashIcon class="size-3.5" /> Busiest tags
        </h3>
        <div class="flex flex-wrap gap-1.5">
          {#each stats.topTags as [tag, count] (tag)}
            <span
              class="flex items-center gap-1 border px-2 py-0.5 text-[11px] text-muted-foreground"
            >
              {tag}
              <span class="text-foreground/70 tabular-nums">{count}</span>
            </span>
          {/each}
        </div>
      </div>
    {/if}
  {/if}
</div>
