<script lang="ts">
  import { onMount } from 'svelte'
  import { fetchEvents } from '$lib/api'
  import { liveEvents, connectionState, subscribeEvents, type OikosEvent } from '$lib/stores/events'
  import * as Table from '$lib/components/ui/table'
  import { Badge } from '$lib/components/ui/badge'
  import { Input } from '$lib/components/ui/input'
  import { Button } from '$lib/components/ui/button'
  import { ScrollArea } from '$lib/components/ui/scroll-area'
  import ChevronDownIcon from '@lucide/svelte/icons/chevron-down'
  import ChevronRightIcon from '@lucide/svelte/icons/chevron-right'

  let history = $state<OikosEvent[]>([])
  let paused = $state(false)
  let typeFilter = $state('')
  let severityFilter = $state('')
  let groupByCorrelation = $state(false)
  let expandedCorrelations = $state<Set<string>>(new Set())

  async function loadHistory() {
    history = await fetchEvents({ type: typeFilter || undefined, severity: severityFilter || undefined })
  }

  onMount(() => {
    loadHistory()
    const unsubscribe = subscribeEvents()
    return unsubscribe
  })

  const feed = $derived.by(() => {
    if (paused) return history
    const seen = new Set(history.map((e) => e.id))
    const merged = [...$liveEvents.filter((e) => !seen.has(e.id)), ...history]
    return merged
      .filter((e) => (!typeFilter || e.type.startsWith(typeFilter)) && (!severityFilter || e.severity === severityFilter))
      .slice(0, 300)
  })

  const clustered = $derived.by(() => {
    if (!groupByCorrelation) return null
    const groups: { corr: string | null; events: OikosEvent[]; latest: number }[] = []
    const seen = new Map<string | null, OikosEvent[]>()
    for (const ev of feed) {
      const key = ev.correlation_id ?? null
      if (!seen.has(key)) seen.set(key, [])
      seen.get(key)!.push(ev)
    }
    for (const [corr, events] of seen) {
      groups.push({ corr, events, latest: Math.max(...events.map((e) => e.id)) })
    }
    groups.sort((a, b) => b.latest - a.latest)
    return groups
  })

  function toggleCorrelation(corr: string | null) {
    const key = corr ?? '__none'
    expandedCorrelations = new Set(expandedCorrelations)
    if (expandedCorrelations.has(key)) {
      expandedCorrelations.delete(key)
    } else {
      expandedCorrelations.add(key)
    }
  }

  function correlationLabel(corr: string | null): string {
    if (!corr) return 'ungrouped'
    return corr.slice(0, 12)
  }

  function severityVariant(sev: string): 'default' | 'secondary' | 'destructive' {
    if (sev === 'critical') return 'destructive'
    if (sev === 'warning') return 'secondary'
    return 'default'
  }

  function mostSevere(events: OikosEvent[]): 'info' | 'warning' | 'critical' {
    if (events.some((e) => e.severity === 'critical')) return 'critical'
    if (events.some((e) => e.severity === 'warning')) return 'warning'
    return 'info'
  }
</script>

<div class="flex h-full flex-col gap-4 p-4 md:p-6">
  <div class="flex items-center justify-between">
    <h1 class="text-lg font-semibold">Live event feed</h1>
    <span class="text-xs text-muted-foreground">
      stream: {$connectionState}
    </span>
  </div>

  <div class="flex items-center gap-2">
    <Input placeholder="Type prefix (e.g. entity.)" bind:value={typeFilter} class="max-w-xs" onchange={loadHistory} />
    <Input placeholder="Severity" bind:value={severityFilter} class="max-w-32" onchange={loadHistory} />
    <Button variant={paused ? 'default' : 'outline'} onclick={() => (paused = !paused)}>
      {paused ? 'Resume' : 'Pause'}
    </Button>
    <Button variant={groupByCorrelation ? 'default' : 'outline'} onclick={() => (groupByCorrelation = !groupByCorrelation)}>
      Groups
    </Button>
    <Button variant="outline" onclick={loadHistory}>Refresh</Button>
  </div>

  <div class="flex-1 overflow-hidden rounded-md border">
    <ScrollArea class="h-full">
      {#if groupByCorrelation && clustered}
        <div class="flex flex-col">
          {#each clustered as group (group.corr ?? '__none')}
            {@const key = group.corr ?? '__none'}
            {@const isExpanded = expandedCorrelations.has(key)}
            <button
              type="button"
              class="flex items-center gap-2 border-b px-4 py-2 text-left text-xs hover:bg-muted/50"
              onclick={() => toggleCorrelation(group.corr)}
            >
              {#if isExpanded}
                <ChevronDownIcon class="size-3 text-muted-foreground" />
              {:else}
                <ChevronRightIcon class="size-3 text-muted-foreground" />
              {/if}
              <Badge variant={severityVariant(mostSevere(group.events))} class="shrink-0"
                >{mostSevere(group.events)}</Badge
              >
              <span class="font-mono">{correlationLabel(group.corr)}</span>
              <span class="text-muted-foreground">{group.events.length} events</span>
              <span class="truncate text-muted-foreground">{group.events[0]?.type ?? ''}</span>
              <span class="grow"></span>
              <span class="text-muted-foreground">{new Date(group.events[0]?.ts ?? '').toLocaleTimeString()}</span>
            </button>
            {#if isExpanded}
              {#each group.events as ev (ev.id)}
                <div class="flex items-center gap-3 border-b py-1 pl-10 pr-4 text-xs">
                  <span class="w-20 shrink-0 font-mono text-muted-foreground"
                    >{new Date(ev.ts).toLocaleTimeString()}</span
                  >
                  <Badge variant={severityVariant(ev.severity)} class="shrink-0">{ev.severity}</Badge>
                  <span class="font-mono">{ev.type}</span>
                  <span class="truncate text-muted-foreground">{ev.source}</span>
                </div>
              {/each}
            {/if}
          {/each}
        </div>
      {:else}
        <Table.Root>
          <Table.Header>
            <Table.Row>
              <Table.Head class="w-32">Time</Table.Head>
              <Table.Head class="w-24">Severity</Table.Head>
              <Table.Head>Type</Table.Head>
              <Table.Head>Source</Table.Head>
              <Table.Head>Correlation</Table.Head>
            </Table.Row>
          </Table.Header>
          <Table.Body>
            {#each feed as ev (ev.id)}
              <Table.Row>
                <Table.Cell class="font-mono text-xs text-muted-foreground"
                  >{new Date(ev.ts).toLocaleTimeString()}</Table.Cell
                >
                <Table.Cell><Badge variant={severityVariant(ev.severity)}>{ev.severity}</Badge></Table.Cell>
                <Table.Cell class="font-mono text-xs">{ev.type}</Table.Cell>
                <Table.Cell class="text-xs text-muted-foreground">{ev.source}</Table.Cell>
                <Table.Cell class="font-mono text-xs text-muted-foreground"
                  >{ev.correlation_id ?? '—'}</Table.Cell
                >
              </Table.Row>
            {:else}
              <Table.Row>
                <Table.Cell colspan={5} class="text-center text-muted-foreground">No events yet.</Table.Cell>
              </Table.Row>
            {/each}
          </Table.Body>
        </Table.Root>
      {/if}
    </ScrollArea>
  </div>
</div>
