import { writable, get } from 'svelte/store'
import { fetchDashboardSummary, fetchApprovals, type DashboardSummary } from '$lib/api'
import { liveEvents, subscribeEvents, type OikosEvent } from './events'

// Shared operational context: dashboard summary + pending approvals,
// refreshed on a slow poll and eagerly on relevant SSE events. Ref-counted
// so the poll only runs while something on screen displays it.

export const summary = writable<DashboardSummary | null>(null)

let refs = 0
let pollTimer: ReturnType<typeof setInterval> | null = null
let unsubscribeSSE: (() => void) | null = null
let unsubscribeStore: (() => void) | null = null
let lastSeenEventId = 0

export async function refreshContext() {
  const [s] = await Promise.all([fetchDashboardSummary(), fetchApprovals('pending')])
  if (s) summary.set(s)
}

function onEvent(ev: OikosEvent) {
  if (ev.id <= lastSeenEventId) return
  lastSeenEventId = ev.id
  // execution.output carries no summary-level change — it just signals that a
  // running command printed more. Excluded so a single noisy command doesn't
  // refresh the dashboard summary once a second.
  if (
    ev.type.startsWith('approval.') ||
    ev.type.startsWith('signal.') ||
    (ev.type.startsWith('execution.') && ev.type !== 'execution.output') ||
    ev.type === 'health.changed'
  ) {
    refreshContext()
  }
}

export function subscribeContext(): () => void {
  refs++
  if (refs === 1) {
    refreshContext()
    pollTimer = setInterval(refreshContext, 30000)
    unsubscribeSSE = subscribeEvents()
    unsubscribeStore = liveEvents.subscribe((events) => {
      if (events[0]) onEvent(events[0])
    })
  }
  return () => {
    refs--
    if (refs === 0) {
      if (pollTimer) clearInterval(pollTimer)
      pollTimer = null
      unsubscribeSSE?.()
      unsubscribeSSE = null
      unsubscribeStore?.()
      unsubscribeStore = null
    }
  }
}

export function openSignalCount(s: DashboardSummary | null): number {
  if (!s) return 0
  return Object.values(s.signals_by_severity).reduce((a, b) => a + b, 0)
}
