import type {Metadata} from 'next';

import {documentTitle} from './documentTitle';

export interface ArtisteName {
  aenPrenom?: string | null;
  aenPatronyme?: string | null;
  aenLibelle?: string | null;
}

/**
 * Nom affiché d'un artiste solo : « Prénom Nom », ou le libellé de l'entrée
 * quand le prénom ou le nom manquent.
 */
export function artisteDisplayName(aen: ArtisteName): string {
  const prenom = aen.aenPrenom?.trim();
  const patronyme = aen.aenPatronyme?.trim();

  if (prenom && patronyme) {
    return `${prenom} ${patronyme}`;
  }

  return aen.aenLibelle?.trim() ?? '';
}

/** Balise title de la fiche d'un artiste solo : « Prénom Nom - Tamm-Kreiz ». */
export function artisteTitle(aen?: ArtisteName | null): string {
  return documentTitle(aen ? artisteDisplayName(aen) : null);
}

/**
 * Métadonnées d'une fiche : le titre de document est construit à partir du libellé chargé,
 * et retombe sur le seul nom du site si le chargement échoue.
 */
export async function ficheMetadata(loadLabel: () => Promise<string | null | undefined>): Promise<Metadata> {
  try {
    return {title: documentTitle(await loadLabel())};
  } catch {
    return {title: documentTitle(null)};
  }
}

export interface VilleTitleSource {
  vilNom: string;
  vilPay?: {payCode?: string; payNom?: string} | null;
  vilSub2?: {subNom?: string | null} | null;
}

/** La France est reconnue par son code ISO, ou par son nom quand l'API ne renvoie pas le code. */
function estEnFrance(pays: VilleTitleSource['vilPay']): boolean {
  return pays?.payCode ? pays.payCode.toUpperCase() === 'FR' : pays?.payNom?.trim() === 'France';
}

/**
 * Libellé d'une ville pour la balise title : « Rennes - Ille-et-Vilaine ». Hors de France,
 * le département n'a pas de sens : c'est le pays qui suit le nom de la ville.
 */
export function villeLabel(vil: VilleTitleSource): string {
  const precision = estEnFrance(vil.vilPay) ? vil.vilSub2?.subNom : vil.vilPay?.payNom;

  return [vil.vilNom.trim(), precision?.trim()].filter(Boolean).join(' - ');
}

/** Balise title d'une ville : « Rennes - Ille-et-Vilaine - Tamm-Kreiz ». */
export function villeTitle(vil: VilleTitleSource): string {
  return documentTitle(villeLabel(vil));
}

export interface EvenementLibelleSource {
  eveTev?: {tevLibelle?: string | null} | null;
  eveVil?: {vilNom?: string | null} | null;
}

/**
 * Titre d'un événement (H1 et balise title) : « Fest-noz à Rennes, samedi 20 septembre 2026 ».
 * La date arrive déjà en toutes lettres, formatée dans la langue de la page.
 */
export function evenementLibelle(event: EvenementLibelleSource, dateLongue: string | null | undefined): string {
  const type = event.eveTev?.tevLibelle?.trim() ?? '';
  const ville = event.eveVil?.vilNom?.trim();
  const ou = ville ? `${type} à ${ville}` : type;
  const date = dateLongue?.trim();

  return date ? `${ou}, ${date}` : ou;
}

export interface StageLibelleSource {
  /** Type d'événement du stage (« Stage »). */
  type: string;
  lieu?: string | null;
  dateDebut: string;
  dateFin?: string | null;
  locale: string;
}

/** « du … au … » dans la langue de la page ; le français sert de repli. */
const SPAN_WORDS: Record<string, [string, string]> = {
  fr: ['du ', ' au '],
  bzh: ['eus ', ' da '],
  en: ['from ', ' to '],
  de: ['vom ', ' bis '],
};

function dateLongue(date: string, locale: string): string {
  return new Intl.DateTimeFormat(locale, {dateStyle: 'full'}).format(new Date(date));
}

/**
 * Titre d'un stage (H1 et balise title) : « Stage à Rennes 35000, samedi 3 octobre 2026 »,
 * ou « …, du samedi 3 octobre 2026 au dimanche 4 octobre 2026 » quand il dure plusieurs jours.
 */
export function stageLibelle({type, lieu, dateDebut, dateFin, locale}: StageLibelleSource): string {
  const ou = lieu?.trim() ? `${type.trim()} à ${lieu.trim()}` : type.trim();
  const debut = dateLongue(dateDebut, locale);

  if (dateFin && dateFin.slice(0, 10) !== dateDebut.slice(0, 10)) {
    const [from, to] = SPAN_WORDS[locale] ?? SPAN_WORDS.fr;

    return `${ou}, ${from}${debut}${to}${dateLongue(dateFin, locale)}`;
  }

  return `${ou}, ${debut}`;
}
