"use client";

import { useEffect, useState } from "react";
import { CheckCircle2, X, AlertTriangle, Info } from "@/components/ui/icons";
import { cn } from "@/lib/utils";

// Toast primitive : feedback global pour les server actions (welcome client,
// password reset envoye, ticket cree, etc). Audit ui-ux-pro-max : sans Toast
// les success/error globaux ne sont annonces nulle part aux lecteurs d'ecran.
//
// Usage :
//   import { toast } from "@/components/ui/toast";
//   toast.success("Compte cree");
//   toast.error("Echec de l'envoi du mail");
//   toast.info("Synchronisation en cours");
//
// Le ToastRegion est monte une seule fois dans app/layout.tsx.

type Tone = "success" | "error" | "info";
type ToastItem = { id: string; tone: Tone; message: string };

// Store module-level : pas de Context React. Les `toast()` appels poussent
// dans le store, ToastRegion s'abonne via useEffect.
const listeners = new Set<(t: ToastItem) => void>();

function push(tone: Tone, message: string) {
  const id = `t_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
  listeners.forEach((cb) => cb({ id, tone, message }));
}

export const toast = {
  success: (message: string) => push("success", message),
  error: (message: string) => push("error", message),
  info: (message: string) => push("info", message),
};

const TONE_CLASSES: Record<Tone, string> = {
  success: "border-success/30 bg-success-soft text-success",
  error: "border-danger/30 bg-danger-soft text-danger",
  info: "border-info/30 bg-info-soft text-info",
};

const TONE_ICONS: Record<Tone, typeof CheckCircle2> = {
  success: CheckCircle2,
  error: AlertTriangle,
  info: Info,
};

export function ToastRegion() {
  const [items, setItems] = useState<ToastItem[]>([]);

  useEffect(() => {
    const onPush = (t: ToastItem) => {
      setItems((prev) => [...prev, t]);
      // Auto-dismiss apres 5s
      window.setTimeout(() => {
        setItems((prev) => prev.filter((x) => x.id !== t.id));
      }, 5000);
    };
    listeners.add(onPush);
    return () => {
      listeners.delete(onPush);
    };
  }, []);

  // Deux regions : polite pour success/info, assertive pour error
  // (recommandation WAI-ARIA pour eviter d'interrompre la lecture en cours).
  const polite = items.filter((t) => t.tone !== "error");
  const assertive = items.filter((t) => t.tone === "error");

  function dismiss(id: string) {
    setItems((prev) => prev.filter((x) => x.id !== id));
  }

  return (
    <>
      <ToastBucket items={polite} ariaLive="polite" onDismiss={dismiss} />
      <ToastBucket items={assertive} ariaLive="assertive" onDismiss={dismiss} />
    </>
  );
}

function ToastBucket({
  items,
  ariaLive,
  onDismiss,
}: {
  items: ToastItem[];
  ariaLive: "polite" | "assertive";
  onDismiss: (id: string) => void;
}) {
  return (
    <div
      aria-live={ariaLive}
      aria-atomic="false"
      className="fixed bottom-4 right-4 z-[60] flex flex-col gap-2 max-w-sm w-[calc(100vw-2rem)] sm:w-auto pointer-events-none"
    >
      {items.map((t) => {
        const Icon = TONE_ICONS[t.tone];
        return (
          <div
            key={t.id}
            role={t.tone === "error" ? "alert" : "status"}
            className={cn(
              "pointer-events-auto flex items-start gap-3 rounded-lg border bg-surface shadow-[var(--shadow-lg)] px-4 py-3 text-sm",
              TONE_CLASSES[t.tone],
            )}
          >
            <Icon className="size-4 shrink-0 mt-0.5" aria-hidden />
            <div className="flex-1 text-text">{t.message}</div>
            <button
              type="button"
              onClick={() => onDismiss(t.id)}
              className="shrink-0 text-text-faint hover:text-text-muted transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/55 rounded"
              aria-label="Fermer la notification"
            >
              <X className="size-3.5" aria-hidden />
            </button>
          </div>
        );
      })}
    </div>
  );
}
