// src/lib/content/analysis.ts — derive the at-a-glance writing analysis for a content item.
import type { SerpSnapshot } from "@/lib/keywords/serp-types";
import type { KeywordBrief } from "@/lib/keywords/ytg-types";
import type { ContentAnalysis } from "./types";

function median(nums: number[]): number | null {
  if (nums.length === 0) return null;
  const s = [...nums].sort((a, b) => a - b);
  const mid = Math.floor(s.length / 2);
  return s.length % 2 ? s[mid] : Math.round((s[mid - 1] + s[mid]) / 2);
}

function mean(nums: number[]): number | null {
  if (nums.length === 0) return null;
  return Math.round(nums.reduce((a, b) => a + b, 0) / nums.length);
}

export function buildContentAnalysis(
  serp: Record<string, SerpSnapshot> | null,
  briefs: Record<string, KeywordBrief> | null,
  locale: string | null,
): ContentAnalysis {
  const snap = locale && serp ? serp[locale] : undefined;
  const comps = snap?.competitors ?? [];
  const nn = (xs: (number | null)[]) =>
    xs.filter((n): n is number => n != null);
  const jsonLdKnown = comps.filter((c) => c.hasJsonLd != null);
  const jsonLdTrue = jsonLdKnown.filter((c) => c.hasJsonLd === true);

  const briefMap = briefs ?? {};
  const briefKeys = Object.keys(briefMap);
  const chosen =
    (locale && briefMap[locale]) ||
    (briefKeys.length ? briefMap[briefKeys[0]] : undefined);
  const briefState: ContentAnalysis["brief"]["state"] =
    locale && briefMap[locale]
      ? "ok"
      : briefKeys.length
        ? "other-locale"
        : "none";

  return {
    serp: {
      state: snap && comps.length > 0 ? "ok" : "none",
      count: comps.length,
      features: snap?.features ?? [],
      medianBacklinks: median(nn(comps.map((c) => c.backlinks))),
      medianAuthority: median(nn(comps.map((c) => c.pageAuthority))),
    },
    onpage: {
      state: !snap ? "none" : snap.crawledAt ? "ok" : "partial",
      crawledAt: snap?.crawledAt ?? null,
      avgImages: mean(nn(comps.map((c) => c.images))),
      jsonLdPct: jsonLdKnown.length
        ? Math.round((jsonLdTrue.length / jsonLdKnown.length) * 100)
        : null,
    },
    brief: {
      state: briefState,
      locale: chosen ? chosen.country || chosen.lang || null : null,
      intent: chosen?.primaryIntent || null,
      subjects: chosen?.keySubjects ?? [],
      questions: chosen?.questions.length ?? 0,
      entities: chosen?.entities ?? [],
    },
  };
}
