import type { EvidenceRecord, EvidenceStrings } from "@/components/Evidence";
import type { VideoRecord, VideoStrings } from "@/components/VideoMedia";
import { getEvidence, getT, type ResolvedEvidence } from "@/lib/content";
import type { Locale } from "@/lib/locales";
import { MODULES } from "@/lib/routes";

/**
 * Shaping gated evidence rows for the component.
 *
 * Everything the component needs is resolved here, on the server: the kicker,
 * the formatted date, the player id. The component receives strings and
 * renders them, which keeps the locale, the route registry and the fact
 * register out of the client bundle.
 */

/**
 * Month and year, in the reader's language.
 *
 * `Intl` already knows the Albanian and Macedonian month abbreviations, so
 * there is no reason to keep twenty-four more strings in the UI file and let
 * them drift. It does add Macedonian's trailing "г." for "година", which is
 * correct prose and noise in a mono metadata strip, so the suffix and the
 * abbreviation dots come off and the result is set upper case like every other
 * piece of metadata on the site.
 */
function formatWhen(locale: Locale, value: string): string {
  if (/^\d{4}$/.test(value)) return value;
  const formatted = new Intl.DateTimeFormat(locale, {
    month: "short",
    year: "numeric",
    timeZone: "UTC",
  }).format(new Date(`${value}-01T00:00:00Z`));
  return formatted
    .replace(/\s*г\.\s*$/u, "")
    .replace(/\./g, "")
    .trim()
    .toLocaleUpperCase(locale);
}

function kickerFor(locale: Locale, subject: ResolvedEvidence["subject"]): string {
  const t = getT(locale);
  if (subject === "company") return t("site.companyName");
  if (subject === "system") return t("site.productName");
  return MODULES.find((module) => module.id === subject)?.brandName ?? t("site.productName");
}

/**
 * The YouTube half: product media.
 *
 * Videos and posts are two different objects on the page, so they are two
 * different shapes here rather than one with a branch in the component. A
 * video is something to watch, with a running time and a play state; a post is
 * a dated citation to go and check.
 */
export function videoRecords(locale: Locale, placement: string): VideoRecord[] {
  return getEvidence(locale, placement)
    .filter((item) => item.source === "youtube")
    .map((item): VideoRecord => ({
      id: item.id,
      videoId: item.ref,
      kicker: kickerFor(locale, item.subject),
      module: item.subject === "system" || item.subject === "company" ? null : item.subject,
      when: item.when ? item.when.slice(0, 4) : null,
      title: item.title,
      duration: item.duration,
      lead: item.lead,
      cta: item.cta,
      href: item.href,
      poster: item.poster ?? null,
      featured: item.featured,
    }));
}

export function VIDEO_STRINGS(locale: Locale): VideoStrings {
  const t = getT(locale);
  return {
    aria: t("media.aria"),
    source: t("evidence.sourceYoutube"),
    note: t("media.note"),
    close: t("support.close"),
    watchOn: t("tutorial.watchOn"),
    playAria: t("tutorial.playAria"),
  };
}

/** The Facebook half: dated citations, with no player and no poster. */
export function evidenceRecords(locale: Locale, placement: string): EvidenceRecord[] {
  const t = getT(locale);

  return getEvidence(locale, placement)
    .filter((item) => item.source === "facebook")
    .map((item): EvidenceRecord => {
      /*
       * Some Facebook posts can only be dated to a year, from a relative
       * timestamp the page showed when the archive was inventoried ("6 years
       * ago"). Those are marked as approximate rather than printed as if the
       * month were known — the whole point of this layer is that a reader can go
       * and check it, and a date that implies more precision than the source has
       * is the one thing that would undermine that.
       */
      const when = item.when
        ? item.dateApprox
          ? t("evidence.approx", { year: item.when.slice(0, 4) }).toLocaleUpperCase(locale)
          : formatWhen(locale, item.when)
        : null;

      return {
        id: item.id,
        source: item.source,
        kicker: kickerFor(locale, item.subject),
        when,
        title: item.title,
        duration: item.duration,
        lead: item.lead,
        cta: item.cta,
        href: item.href,
        videoId: null,
      };
    });
}

export function EVIDENCE_STRINGS(locale: Locale): EvidenceStrings {
  const t = getT(locale);
  return {
    aria: t("evidence.aria"),
    sourceYoutube: t("evidence.sourceYoutube"),
    sourceFacebook: t("evidence.sourceFacebook"),
    note: t("evidence.note"),
    close: t("support.close"),
    watchOn: t("tutorial.watchOn"),
    externalLink: t("a11y.externalLink"),
  };
}
