// Abo-System: Preise/Rabatte/Verhaltensregeln kommen aus dem Adminbereich (Decap CMS, siehe
// public/admin/config.yml → "🎁 Abo-System" → src/content/abo-einstellungen.json). Reine,
// zustandslose Berechnungsfunktionen — der eigentliche Konto-Zustand (welches Abo, wie viele
// bezahlte Monate, freigeschaltete Prämien) lebt in scripts/account.ts.

// @ts-ignore -- JSON-Import, zur Build-Zeit von Astro/Vite aufgelöst
import raw from "../content/abo-einstellungen.json";

export type AboStufe = "klein" | "mittel" | "gross";

export interface MehrsprachigerText {
  de: string;
  en: string;
  ch: string;
  fr: string;
}

export interface AboStufenKonfig {
  preis: number;
  rabattProzent: number;
  /** Ob diese Stufe aktuell neu buchbar ist. Bestehende Abonnent:innen dieser Stufe behalten
   *  ihre Vorteile unabhängig davon — nur NEUE Buchungen werden im Kundenkonto gesperrt. */
  aktiv: boolean;
  /** Nach wie vielen durchgehend bezahlten Monaten es jeweils einen kleinen/großen Teddy gibt.
   *  0 oder nicht gesetzt = diese Stufe kennt diese Prämienart gar nicht. Admin-editierbar,
   *  ersetzt die früher fest im Code verankerten 6-/12-Monats-Intervalle. */
  kleinIntervallMonate: number;
  grossIntervallMonate: number;
  /** Anzeigename/Vorteilstext der Stufe, pro Sprache — ersetzt die früher fest in i18n/ui.ts
   *  verankerten Texte, damit VanVan Name und Beschreibung jeder Stufe selbst pflegen kann. */
  name: MehrsprachigerText;
  vorteil: MehrsprachigerText;
}

export interface AboEinstellungen {
  klein: AboStufenKonfig;
  mittel: AboStufenKonfig;
  gross: AboStufenKonfig;
  /** Produkt-Slugs (siehe src/content/products/*.json), die als "kleiner"/"großer" Teddy für
   *  die Prämien-Einlösung verwendet werden — im Admin per Produkt-Auswahl änderbar. */
  kleinTeddySlug: string;
  grossTeddySlug: string;
  kombinierbarMitAnderenRabatten: boolean;
  versandKostenlosBeiPraemie: boolean;
  fortsetzungBeiWiederanmeldung: boolean;
  monateUeberStufenZusammenzaehlen: boolean;
}

export const aboEinstellungen = raw as AboEinstellungen;

export function aboStufenKonfig(stufe: AboStufe): AboStufenKonfig {
  return aboEinstellungen[stufe];
}

export const ABO_STUFEN: AboStufe[] = ["klein", "mittel", "gross"];

/** Name/Vorteilstext der Stufe in der gewünschten Sprache, mit Fallback auf Deutsch, falls das
 *  Feld im Admin (noch) leer gelassen wurde. */
export function aboStufeName(stufe: AboStufe, lang: keyof MehrsprachigerText): string {
  const cfg = aboStufenKonfig(stufe);
  return cfg.name?.[lang] || cfg.name?.de || stufe;
}
export function aboStufeVorteil(stufe: AboStufe, lang: keyof MehrsprachigerText): string {
  const cfg = aboStufenKonfig(stufe);
  return cfg.vorteil?.[lang] || cfg.vorteil?.de || "";
}

/** Wie viele Teddy-Prämien welcher Art bei X durchgehend bezahlten Monaten in dieser Stufe
 *  INSGESAMT freigeschaltet sein müssten (kumulativ, nicht nur "neu diesen Monat") — rechnet
 *  rein aus den admin-konfigurierten Intervallen (siehe AboStufenKonfig), keine fest im Code
 *  verankerten Zahlen mehr. Ein Intervall von 0 (oder nicht gesetzt) bedeutet "diese Stufe
 *  kennt diese Prämienart nicht". */
export function teddyMeilensteine(stufe: AboStufe, monate: number): { klein: number; gross: number } {
  if (monate <= 0) return { klein: 0, gross: 0 };
  const cfg = aboStufenKonfig(stufe);
  const kleinIntervall = cfg.kleinIntervallMonate || 0;
  const grossIntervall = cfg.grossIntervallMonate || 0;
  return {
    klein: kleinIntervall > 0 ? Math.floor(monate / kleinIntervall) : 0,
    gross: grossIntervall > 0 ? Math.floor(monate / grossIntervall) : 0,
  };
}

/** Wie viele Monate fehlen noch bis zum jeweils nächsten Meilenstein (für die
 *  Fortschrittsanzeige im Kundenkonto), null wenn diese Stufe die Prämienart gar nicht kennt. */
export function naechsteMeilensteine(stufe: AboStufe, monate: number): { klein: number | null; gross: number | null } {
  const cfg = aboStufenKonfig(stufe);
  const kleinIntervall = cfg.kleinIntervallMonate || 0;
  const grossIntervall = cfg.grossIntervallMonate || 0;
  return {
    klein: kleinIntervall > 0 ? kleinIntervall - (monate % kleinIntervall) : null,
    gross: grossIntervall > 0 ? grossIntervall - (monate % grossIntervall) : null,
  };
}

/** Ein Abo ist aktiv, solange der aktuell bezahlte Abrechnungszeitraum noch nicht abgelaufen
 *  ist — reiner Datumsvergleich zur echten, aktuellen Uhrzeit (läuft also automatisch ab, ganz
 *  ohne Cronjob/Backend), genau wie befristete Produkt-Rabatte (siehe data/rabatt.ts). Gilt
 *  bewusst UNABHÄNGIG davon, ob das Abo schon gekündigt wurde — gekündigte Abos behalten ihre
 *  Vorteile bis zum Ende der bezahlten Laufzeit. */
export function aboAktuellAktiv(bezahltBisDatum: string | null): boolean {
  if (!bezahltBisDatum) return false;
  return new Date() <= new Date(`${bezahltBisDatum}T23:59:59`);
}

/** Heutiges Datum als lokales Kalenderdatum (NICHT über toISOString(), das auf UTC umrechnet und
 *  in Zeitzonen östlich von UTC nachts kurzzeitig das falsche — gestrige — Datum liefern würde). */
export function heutigesDatumISO(): string {
  const heute = new Date();
  const jahr = heute.getFullYear();
  const monat = String(heute.getMonth() + 1).padStart(2, "0");
  const tag = String(heute.getDate()).padStart(2, "0");
  return `${jahr}-${monat}-${tag}`;
}

/** Rechnet rein kalendarisch in UTC (bewusst NICHT über lokale Zeit + toISOString() gemischt —
 *  das würde je nach Zeitzone des Geräts bei jedem Aufruf einen Tag "verlieren" und sich über
 *  viele Monate hinweg zu einem spürbaren Datumsfehler aufsummieren; mit reinem UTC-Rechnen ist
 *  das Ergebnis unabhängig von der Zeitzone des Kunden immer exakt). */
export function addMonateISO(datumISO: string, monate: number): string {
  const [jahr, monat, tag] = datumISO.split("-").map(Number);
  return new Date(Date.UTC(jahr, monat - 1 + monate, tag)).toISOString().slice(0, 10);
}
