/**
 * GET /api/activity/summary
 *
 * Small snapshot for the Activity pill / dashboard. Three sections:
 *   - running:  pipelines currently in flight (status queued|running)
 *   - upcoming: enabled schedules sorted by next_run_at ASC
 *   - recent:   last 8 finished pipelines (succeeded|failed|cancelled)
 *
 * Aim <5KB response, <30ms. No expensive joins, no per-pipeline detail.
 * Front-end refetches every 5s when ActivityPanel is open.
 */

import { NextResponse } from 'next/server';
import { listPipelinesSummary } from '@/lib/pipeline';
import { listSchedules } from '@/lib/schedules/store';

interface RunningRow {
  id: string;
  workflowName: string;
  status: string;
  currentNode: string | null;
  progress: { done: number; total: number };
  createdAt: string;
}

interface UpcomingRow {
  id: string;
  name: string;
  body_kind: string;
  body_ref: string;
  next_run_at: string | null;
  schedule_kind: string;
  schedule_summary: string;
}

interface RecentRow {
  id: string;
  workflowName: string;
  status: string;
  completedAt: string | null;
  durationMs: number | null;
}

interface Summary {
  running: RunningRow[];
  upcoming: UpcomingRow[];
  recent: RecentRow[];
  generated_at: string;
}

function scheduleSummary(s: {
  schedule_kind: string;
  schedule_interval_minutes: number;
  schedule_at: string | null;
  schedule_cron: string | null;
}): string {
  switch (s.schedule_kind) {
    case 'period':
      return s.schedule_interval_minutes >= 60
        ? `every ${Math.round(s.schedule_interval_minutes / 60)}h`
        : `every ${s.schedule_interval_minutes}m`;
    case 'cron':
      return `cron: ${s.schedule_cron || '?'}`;
    case 'once':
      return s.schedule_at ? `at ${s.schedule_at}` : 'one-shot';
    case 'manual':
      return 'manual only';
    default:
      return s.schedule_kind;
  }
}

export async function GET() {
  // Single listPipelinesSummary call — uses the parse cache, sorted desc.
  // 200 runs cap is plenty; we'll filter into running + recent and discard
  // the rest.
  const all = listPipelinesSummary({ limit: 200 });

  const running: RunningRow[] = [];
  const recent: RecentRow[] = [];
  for (const p of all) {
    const isActive = p.status === 'running';
    if (isActive && running.length < 30) {
      // Compute progress + current node from the in-memory nodes map.
      let done = 0;
      let current: string | null = null;
      for (const name of p.nodeOrder) {
        const st = p.nodes[name]?.status;
        if (st === 'done' || st === 'skipped') done++;
        else if (!current && st === 'running') current = name;
      }
      running.push({
        id: p.id,
        workflowName: p.workflowName,
        status: p.status,
        currentNode: current,
        progress: { done, total: p.nodeOrder.length },
        createdAt: p.createdAt,
      });
    } else if (!isActive && recent.length < 8) {
      const startedMs = Date.parse(p.createdAt);
      const endedMs = p.completedAt ? Date.parse(p.completedAt) : NaN;
      recent.push({
        id: p.id,
        workflowName: p.workflowName,
        status: p.status,
        completedAt: p.completedAt || null,
        durationMs: isFinite(startedMs) && isFinite(endedMs) ? endedMs - startedMs : null,
      });
    }
  }

  // Upcoming = enabled schedules sorted by next_run_at ASC, top 10.
  const schedules = listSchedules()
    .filter((s) => s.enabled && s.next_run_at)
    .sort((a, b) => String(a.next_run_at).localeCompare(String(b.next_run_at)))
    .slice(0, 10);
  const upcoming: UpcomingRow[] = schedules.map((s) => ({
    id: s.id,
    name: s.name,
    body_kind: s.body_kind,
    body_ref: s.body_ref,
    next_run_at: s.next_run_at,
    schedule_kind: s.schedule_kind,
    schedule_summary: scheduleSummary(s),
  }));

  const summary: Summary = {
    running,
    upcoming,
    recent,
    generated_at: new Date().toISOString(),
  };
  return NextResponse.json(summary);
}
