import type { AssessmentAnswers, Classification, ContentPack, Obligation } from './types';

/**
 * Leitet die anwendbaren Pflichten für ein klassifiziertes System ab.
 *
 * Auswahlkriterien je Pflicht: Risikoklasse und Rolle müssen passen;
 * GPAI- und Transparenzpflichten werden nur bei entsprechendem Flag
 * aufgenommen. Zusätzlich werden die Pflichten der aktivierten
 * nationalen Module (Länderauswahl) einbezogen.
 *
 * @param classification - Ergebnis von {@link classify}
 * @param answers - Wizard-Antworten (Rolle, GPAI-Flag)
 * @param pack - Regulatorischer Content-Pack
 * @param countries - Aktivierte Länder-Module (ISO-Codes, z. B. ["DE","IT"])
 * @returns Deduplizierte, nach Frist sortierte Pflichtenliste
 */
export function deriveObligations(
  classification: Classification,
  answers: AssessmentAnswers,
  pack: ContentPack,
  countries: readonly string[] = [],
): readonly Obligation[] {
  if (classification.riskClass === 'out-of-scope' || classification.riskClass === 'prohibited') {
    return [];
  }

  const matches = (ob: Obligation): boolean => {
    if (ob.id === 'ob-gpai') {
      return classification.gpaiObligations && answers.role === 'provider';
    }
    if (ob.id === 'ob-transparency-art50') {
      return classification.transparencyDuties && ob.roles.includes(answers.role);
    }
    return ob.riskClasses.includes(classification.riskClass) && ob.roles.includes(answers.role);
  };

  const euObligations = pack.obligations.filter(matches);
  const nationalObligations = pack.national
    .filter((n) => countries.includes(n.code))
    .flatMap((n) => n.items.filter(matches));

  return [...euObligations, ...nationalObligations].sort((a, b) =>
    a.deadline.localeCompare(b.deadline),
  );
}

/**
 * Ermittelt die nächste noch bevorstehende Geltungsfrist für ein System.
 *
 * @param obligations - Anwendbare Pflichten des Systems
 * @param today - Stichtag im ISO-Format (YYYY-MM-DD)
 * @returns Früheste Frist nach dem Stichtag, oder null wenn alle verstrichen
 */
export function nextDeadline(
  obligations: readonly Obligation[],
  today: string,
): string | null {
  const upcoming = obligations
    .map((ob) => ob.deadline)
    .filter((d) => d >= today)
    .sort();
  return upcoming[0] ?? null;
}
