import { format, formatDistanceToNowStrict, parseISO } from "date-fns";
import { fr } from "date-fns/locale";
import { MINUTES_PER_RUBIS } from "@rubis/shared";

/**
 * Formateurs métier — centralisés pour cohérence d'affichage.
 * Cf. /docs/tech/frontend.md §9.
 */

/** "1 240,00 €" depuis un montant en centimes. */
export function formatEuros(cents: number): string {
  return new Intl.NumberFormat("fr-FR", {
    style: "currency",
    currency: "EUR",
    minimumFractionDigits: 2,
  }).format(cents / 100);
}

/**
 * Convertit un nombre de rubis en libellé "X h Y" (1 rubis = 10 min).
 * Ex : 124 rubis → "20 h 40".
 */
export function formatRubisToHours(rubis: number): string {
  const totalMinutes = rubis * MINUTES_PER_RUBIS;
  const hours = Math.floor(totalMinutes / 60);
  const minutes = totalMinutes % 60;
  if (hours === 0) return `${minutes} min`;
  if (minutes === 0) return `${hours} h`;
  return `${hours} h ${minutes.toString().padStart(2, "0")}`;
}

/** "5 mai 2026" depuis une date ISO. */
export function formatDate(iso: string): string {
  return format(parseISO(iso), "d MMMM yyyy", { locale: fr });
}

/** "dans 3 jours" / "il y a 2 jours" depuis maintenant. */
export function formatRelativeDate(iso: string): string {
  return formatDistanceToNowStrict(parseISO(iso), { locale: fr, addSuffix: true });
}

/** "5 mai" version courte. */
export function formatDateShort(iso: string): string {
  return format(parseISO(iso), "d MMM", { locale: fr });
}

/**
 * Délai par rapport à aujourd'hui pour une échéance ISO :
 *  - "J−3" si dépassée de 3 jours
 *  - "J+10" si dans 10 jours
 *  - "Aujourd'hui" si dans la journée
 *
 * Convention : le signe '−' (minus typographique, pas hyphen) marque le retard.
 * Pas d'espace autour de J — c'est un token visuel compact.
 */
export function formatDueDelta(iso: string, now: Date = new Date()): string {
  const due = parseISO(iso);
  // Compare en jours calendaires (pas en ms exactes).
  const oneDay = 24 * 60 * 60 * 1000;
  const dueDay = Math.floor(due.getTime() / oneDay);
  const today = Math.floor(now.getTime() / oneDay);
  const diff = dueDay - today;
  if (diff === 0) return "Aujourd'hui";
  if (diff < 0) return `J−${Math.abs(diff)}`;
  return `J+${diff}`;
}

/** True si l'échéance est passée (strict, pas le jour même). */
export function isOverdue(iso: string, now: Date = new Date()): boolean {
  return parseISO(iso).getTime() < now.setHours(0, 0, 0, 0);
}
