/**
 * Tokens et primitives partagés par tous les charts Rubis.
 * On reste **strict** sur la palette : que des couleurs marque (rubis +
 * neutres chauds), pas de bleu/vert/catégoriel générique de BI dashboard.
 */

import type { CSSProperties } from "react";

/** Lit la valeur d'une CSS custom-property posée par @theme dans app.css. */
function cssVar(name: string): string {
  // Côté SSR / tests, document est absent — on fallback hex.
  if (typeof window === "undefined") return "";
  return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
}

/**
 * Couleurs résolues à l'usage (pas en module-scope car les CSS vars
 * peuvent ne pas être prêtes au tout premier import). Cf. `chartColors()`.
 */
export function chartColors() {
  return {
    rubis: cssVar("--color-rubis") || "#9F1239",
    rubisDeep: cssVar("--color-rubis-deep") || "#771328",
    rubisLight: cssVar("--color-rubis-light") || "#C9415C",
    rubisGlow: cssVar("--color-rubis-glow") || "#FBE4EA",
    cream: cssVar("--color-cream") || "#FAF7F2",
    cream2: cssVar("--color-cream-2") || "#F5EFE7",
    line: cssVar("--color-line") || "#E8E0D6",
    ink: cssVar("--color-ink") || "#1A1410",
    ink2: cssVar("--color-ink-2") || "#4F4640",
    ink3: cssVar("--color-ink-3") || "#8A7F76",
  };
}

/**
 * Couleur d'un statut de facture — réutilise l'identité des badges côté
 * liste pour que pipeline charts et tableaux racontent la même histoire.
 */
export const STATUS_COLOR: Record<string, string> = {
  pending: "#E8E0D6", // line — neutre, en attente
  awaiting_user_confirmation: "#FBE4EA", // rubis-glow
  in_relance: "#9F1239", // rubis primaire
  litigation: "#1A1410", // ink — sérieux
  paid: "#771328", // rubis-deep
};

export const STATUS_LABEL: Record<string, string> = {
  pending: "En attente",
  awaiting_user_confirmation: "Confirmation en cours",
  in_relance: "En relance",
  litigation: "Litige",
  paid: "Encaissé",
};

/** Style label commun pour les axes (Inter, tabular-nums, ink-3). */
export const AXIS_TICK_STYLE: CSSProperties = {
  fontFamily: "var(--font-sans)",
  fontSize: 11,
  fontFeatureSettings: '"tnum"',
  fill: "var(--color-ink-3)",
};

/** Granularité d'agrégation d'une série temporelle (mensuelle ou hebdo). */
export type SeriesGranularity = "month" | "week";

/** Format mois "2026-04-01" → "avr" pour les ticks X compacts. */
const MONTH_FORMAT = new Intl.DateTimeFormat("fr-FR", { month: "short" });
export function formatMonthShort(monthIso: string): string {
  // "2026-04-01" → date locale (no need for parseISO, Date est suffisant)
  const d = new Date(monthIso);
  if (Number.isNaN(d.getTime())) return monthIso;
  return MONTH_FORMAT.format(d).replace(".", "");
}

/** Format mois long pour les tooltips. */
const MONTH_LONG = new Intl.DateTimeFormat("fr-FR", {
  month: "long",
  year: "numeric",
});
export function formatMonthLong(monthIso: string): string {
  const d = new Date(monthIso);
  if (Number.isNaN(d.getTime())) return monthIso;
  return MONTH_LONG.format(d);
}

/** Format jour court "12 mai" pour les ticks X de la vue hebdo. */
const DAY_SHORT = new Intl.DateTimeFormat("fr-FR", {
  day: "numeric",
  month: "short",
});
export function formatDayShort(iso: string): string {
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return iso;
  return DAY_SHORT.format(d).replace(".", "");
}

/** Format "Semaine du 12 mai 2026" pour les tooltips hebdo. */
const DAY_LONG = new Intl.DateTimeFormat("fr-FR", {
  day: "numeric",
  month: "long",
  year: "numeric",
});
export function formatWeekLong(iso: string): string {
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return iso;
  return `Semaine du ${DAY_LONG.format(d)}`;
}

/** Sélecteur unifié — formate un bucket selon la granularité. */
export function formatBucketShort(
  iso: string,
  granularity: SeriesGranularity,
): string {
  return granularity === "week" ? formatDayShort(iso) : formatMonthShort(iso);
}

export function formatBucketLong(
  iso: string,
  granularity: SeriesGranularity,
): string {
  return granularity === "week" ? formatWeekLong(iso) : formatMonthLong(iso);
}
