// src/lib/content/overview.ts — pure content overview aggregation.
import type { ContentStatus } from "@/lib/db/domain-schema";
import { isOverdue } from "./board";
import type { ContentItem } from "./types";
import { CONTENT_STATUSES } from "./types";

export interface CountBy<K> {
  key: K;
  count: number;
}
export interface UpcomingRow {
  id: string;
  title: string;
  status: ContentStatus;
  dueDate: string;
  overdue: boolean;
}
export interface ContentOverview {
  total: number;
  byStatus: CountBy<ContentStatus>[];
  published: number;
  inProgress: number;
  overdue: number;
  withBrief: number;
  unlinked: number;
  byAssignee: CountBy<string>[];
  upcoming: UpcomingRow[];
}

export function buildContentOverview(
  items: ContentItem[],
  nowIso: string,
): ContentOverview {
  const statusCounts = new Map<ContentStatus, number>(
    CONTENT_STATUSES.map((s) => [s, 0]),
  );
  for (const it of items)
    statusCounts.set(it.status, (statusCounts.get(it.status) ?? 0) + 1);

  const assigneeCounts = new Map<string, number>();
  for (const it of items) {
    const key = it.assignee?.trim() || "Non assigné";
    assigneeCounts.set(key, (assigneeCounts.get(key) ?? 0) + 1);
  }

  const overdue = items.filter(
    (it) => it.status !== "published" && isOverdue(it.dueDate, nowIso),
  ).length;

  const upcoming: UpcomingRow[] = items
    .filter((it) => it.dueDate)
    .sort((a, b) => ((a.dueDate as string) < (b.dueDate as string) ? -1 : 1))
    .slice(0, 8)
    .map((it) => ({
      id: it.id,
      title: it.title,
      status: it.status,
      dueDate: it.dueDate as string,
      overdue: it.status !== "published" && isOverdue(it.dueDate, nowIso),
    }));

  return {
    total: items.length,
    byStatus: CONTENT_STATUSES.map((key) => ({
      key,
      count: statusCounts.get(key) ?? 0,
    })),
    published: statusCounts.get("published") ?? 0,
    inProgress:
      (statusCounts.get("writing") ?? 0) + (statusCounts.get("review") ?? 0),
    overdue,
    withBrief: items.filter((it) => it.hasBrief).length,
    unlinked: items.filter((it) => it.primaryKeywordId === null).length,
    byAssignee: [...assigneeCounts.entries()]
      .map(([key, count]) => ({ key, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 6),
    upcoming,
  };
}
