/**
 * src/http/digest.ts (W3 quick-wins c) — "while you were away" reconnect digest.
 *
 * A PURE read-side aggregate over the live-session list (injected, like
 * buildProjects) plus each session's in-memory telemetry/status. No new state:
 * it only projects what the manager already tracks into a compact summary the FE
 * shows as a banner on (re)connect.
 *
 * `since` is a client's last-seen epoch-ms watermark: a session counts as
 * `finished` when it is idle AND produced output after `since`. A bad/absent
 * `since` clamps to 0 ("everything is new").
 */

import path from 'node:path'
import type { DigestResult, DigestSession, LiveSessionInfo } from '../types.js'

/** Last path segment of a cwd (the session "title"), or undefined. */
function lastSegment(cwd: string | null): string | undefined {
  if (cwd === null || cwd === '') return undefined
  return cwd.split(path.sep).filter(Boolean).pop()
}

/** Clamp `since` to a finite, non-negative number (bad/absent → 0). */
export function clampSince(since: unknown): number {
  const n = typeof since === 'number' ? since : Number(since)
  return Number.isFinite(n) && n >= 0 ? n : 0
}

/** Project one live session into its digest row. */
function toDigestSession(s: LiveSessionInfo, since: number): DigestSession {
  const title = lastSegment(s.cwd)
  const costUsd = s.telemetry?.costUsd
  const lastOutputAt = s.lastOutputAt
  const finished = s.status === 'idle' && lastOutputAt !== undefined && lastOutputAt > since
  return {
    id: s.id,
    ...(title !== undefined ? { title } : {}),
    status: s.status,
    ...(costUsd !== undefined ? { costUsd } : {}),
    ...(lastOutputAt !== undefined ? { lastOutputAt } : {}),
    finished,
    needsInput: s.status === 'waiting',
    stuck: s.status === 'stuck',
  }
}

/**
 * Build the reconnect digest from the live-session list. Pure — the list is
 * injected (e.g. `manager.list()`). Empty list → all-zero aggregate. Never throws.
 */
export function buildDigest(live: readonly LiveSessionInfo[], since: number): DigestResult {
  const clampedSince = clampSince(since)
  const sessions = live.map((s) => toDigestSession(s, clampedSince))

  let finished = 0
  let needsInput = 0
  let stuck = 0
  let working = 0
  let totalCostUsd = 0
  for (const d of sessions) {
    if (d.finished) finished += 1
    if (d.needsInput) needsInput += 1
    if (d.stuck) stuck += 1
    if (d.status === 'working') working += 1
    if (d.costUsd !== undefined) totalCostUsd += d.costUsd
  }

  return {
    since: clampedSince,
    generatedAt: Date.now(),
    total: sessions.length,
    finished,
    needsInput,
    stuck,
    working,
    totalCostUsd,
    sessions,
  }
}
