// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
/**
 * Gestionnaire de consentement aux témoins (Loi 25) :
 * bandeau au premier passage + panneau de préférences réouvrable partout
 * (événement window « vp-open-cookie-prefs » ou bouton du pied de page).
 * Choix conservé 12 mois dans localStorage (vp-cookie-consent).
 */
"use client";
import { useEffect, useState } from "react";
import { useLang } from "./LangContext";

export interface ConsentState {
  essential: true;
  preferences: boolean;
  analytics: boolean;
  savedAt: string;
}

const KEY = "vp-cookie-consent";
const MAX_AGE_DAYS = 365;

export function readConsent(): ConsentState | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = window.localStorage.getItem(KEY);
    if (!raw) return null;
    const c = JSON.parse(raw) as ConsentState;
    const age = (Date.now() - new Date(c.savedAt).getTime()) / 86400000;
    return age > MAX_AGE_DAYS ? null : c;
  } catch {
    return null;
  }
}

export function openCookiePrefs() {
  window.dispatchEvent(new Event("vp-open-cookie-prefs"));
}

const TXT = {
  fr: {
    banner:
      "Vrai-Prix utilise un minimum de témoins : des essentiels (fonctionnement du site) et, si vous l'acceptez, un témoin de préférences pour retenir votre langue. Aucun témoin publicitaire, aucun pistage tiers.",
    acceptAll: "Tout accepter",
    essentialOnly: "Essentiels seulement",
    customize: "Personnaliser",
    prefsTitle: "Préférences de témoins",
    essential: "Essentiels",
    essentialDesc: "Nécessaires au fonctionnement (sécurité, session). Toujours actifs.",
    prefs: "Préférences",
    prefsDesc: "Retient votre langue d'affichage (FR/EN) sur cet appareil, 12 mois.",
    analytics: "Mesure d'audience",
    analyticsDesc: "Aucun outil de mesure n'est actuellement utilisé. Ce réglage s'appliquera si un jour un outil respectueux est ajouté.",
    always: "Toujours actifs",
    save: "Enregistrer mes choix",
    more: "Politique de confidentialité",
  },
  en: {
    banner:
      "Vrai-Prix uses a minimum of cookies: essential ones (site operation) and, with your consent, a preference cookie to remember your language. No advertising cookies, no third-party tracking.",
    acceptAll: "Accept all",
    essentialOnly: "Essential only",
    customize: "Customize",
    prefsTitle: "Cookie preferences",
    essential: "Essential",
    essentialDesc: "Required for operation (security, session). Always on.",
    prefs: "Preferences",
    prefsDesc: "Remembers your display language (FR/EN) on this device for 12 months.",
    analytics: "Analytics",
    analyticsDesc: "No analytics tool is currently used. This setting will apply if a privacy-respecting tool is ever added.",
    always: "Always on",
    save: "Save my choices",
    more: "Privacy policy",
  },
};

function Toggle({
  on,
  disabled,
  onChange,
}: {
  on: boolean;
  disabled?: boolean;
  onChange?: (v: boolean) => void;
}) {
  return (
    <button
      type="button"
      role="switch"
      aria-checked={on}
      disabled={disabled}
      onClick={() => onChange?.(!on)}
      className={`relative h-7 w-12 shrink-0 rounded-full border-[1.5px] border-ink transition-colors ${
        on ? "bg-lime" : "bg-surface-2"
      } ${disabled ? "cursor-not-allowed opacity-70" : "cursor-pointer"}`}
    >
      <span
        className={`absolute top-[2.5px] h-[18px] w-[18px] rounded-full bg-ink transition-all ${
          on ? "left-[26px]" : "left-[3px]"
        }`}
      />
    </button>
  );
}

export default function CookieConsent() {
  const { lang } = useLang();
  const t = TXT[lang];
  const [ready, setReady] = useState(false);
  const [consent, setConsent] = useState<ConsentState | null>(null);
  const [panel, setPanel] = useState(false);
  const [prefs, setPrefs] = useState(true);
  const [analytics, setAnalytics] = useState(false);

  useEffect(() => {
    const id = setTimeout(() => {
      const c = readConsent();
      setConsent(c);
      if (c) {
        setPrefs(c.preferences);
        setAnalytics(c.analytics);
      }
      setReady(true);
    }, 0);
    const open = () => setPanel(true);
    window.addEventListener("vp-open-cookie-prefs", open);
    return () => {
      clearTimeout(id);
      window.removeEventListener("vp-open-cookie-prefs", open);
    };
  }, []);

  const persist = (preferences: boolean, analyticsOn: boolean) => {
    const c: ConsentState = {
      essential: true,
      preferences,
      analytics: analyticsOn,
      savedAt: new Date().toISOString(),
    };
    window.localStorage.setItem(KEY, JSON.stringify(c));
    if (!preferences) window.localStorage.removeItem("vp-lang");
    setConsent(c);
    setPanel(false);
  };

  if (!ready) return null;
  const showBanner = consent === null && !panel;

  return (
    <>
      {showBanner && (
        <div className="fixed inset-x-0 bottom-0 z-[1300] p-3 sm:p-5">
          <div className="mx-auto max-w-3xl rounded-[10px] border-[1.5px] border-ink bg-ink p-5 text-paper shadow-[0_-8px_32px_rgba(16,18,16,0.35),6px_6px_0_rgba(20,24,20,0.3)]">
            <p className="klabel !text-lime">🍪 {t.prefsTitle}</p>
            <p className="mt-2 text-[13.5px] leading-relaxed text-[rgba(245,243,238,0.85)]">
              {t.banner}{" "}
              <a href="/confidentialite" className="border-b border-lime text-lime">
                {t.more}
              </a>
            </p>
            <div className="mt-4 flex flex-wrap gap-2.5">
              <button className="btn border-lime bg-lime text-ink" onClick={() => persist(true, true)}>
                {t.acceptAll}
              </button>
              <button
                className="btn border-[rgba(245,243,238,0.5)] bg-transparent text-paper hover:bg-[rgba(245,243,238,0.12)]"
                onClick={() => persist(false, false)}
              >
                {t.essentialOnly}
              </button>
              <button
                className="btn border-[rgba(245,243,238,0.5)] bg-transparent text-paper hover:bg-[rgba(245,243,238,0.12)]"
                onClick={() => setPanel(true)}
              >
                {t.customize}
              </button>
            </div>
          </div>
        </div>
      )}

      {panel && (
        <div
          className="fixed inset-0 z-[1400] flex items-end justify-center bg-[rgba(16,18,16,0.55)] p-3 backdrop-blur-[2px] sm:items-center"
          onClick={() => setPanel(false)}
        >
          <div
            className="w-full max-w-lg rounded-[10px] border-[1.5px] border-ink bg-surface p-6 shadow-[8px_8px_0_rgba(20,24,20,0.3)]"
            onClick={(e) => e.stopPropagation()}
            role="dialog"
            aria-modal="true"
            aria-label={t.prefsTitle}
          >
            <h2 className="vp-display text-[19px] font-bold uppercase tracking-[-0.01em]">
              {t.prefsTitle}
            </h2>
            <div className="mt-4 space-y-3">
              {[
                { k: t.essential, d: t.essentialDesc, on: true, lock: true, set: undefined },
                { k: t.prefs, d: t.prefsDesc, on: prefs, lock: false, set: setPrefs },
                { k: t.analytics, d: t.analyticsDesc, on: analytics, lock: false, set: setAnalytics },
              ].map((row) => (
                <div key={row.k} className="flex items-start justify-between gap-4 rounded-lg border-[1.5px] border-[rgba(20,24,20,0.14)] bg-surface-2 p-4">
                  <div>
                    <p className="vp-display text-[14px] font-bold">
                      {row.k}
                      {row.lock && (
                        <span className="vp-mono ml-2 text-[9px] font-bold uppercase tracking-[0.08em] text-green-deep">
                          {t.always}
                        </span>
                      )}
                    </p>
                    <p className="mt-1 text-[12.5px] text-ink-2">{row.d}</p>
                  </div>
                  <Toggle on={row.on} disabled={row.lock} onChange={row.set} />
                </div>
              ))}
            </div>
            <button className="btn btn-primary mt-5 w-full" onClick={() => persist(prefs, analytics)}>
              {t.save}
            </button>
          </div>
        </div>
      )}
    </>
  );
}
