"use client";

import {
  createContext,
  useCallback,
  useContext,
  useState,
  useEffect,
  useRef,
  type ReactNode,
} from "react";

// ── Types ─────────────────────────────────────────────────────────────────────
export type ToastVariant = "success" | "error" | "info" | "warning";

export interface Toast {
  id: string;
  message: string;
  variant: ToastVariant;
  duration?: number;
  leaving?: boolean;
}

interface ToastContextValue {
  toast: (message: string, variant?: ToastVariant, duration?: number) => void;
  success: (message: string) => void;
  error: (message: string) => void;
  info: (message: string) => void;
  warning: (message: string) => void;
}

// ── Context ───────────────────────────────────────────────────────────────────
const ToastContext = createContext<ToastContextValue | null>(null);

// ── Hook ──────────────────────────────────────────────────────────────────────
export function useToast() {
  const ctx = useContext(ToastContext);
  if (!ctx) throw new Error("useToast must be used inside ToastProvider");
  return ctx;
}

// ── Toast Item ────────────────────────────────────────────────────────────────
const VARIANT_STYLES: Record<ToastVariant, { bg: string; border: string; icon: string }> = {
  success: { bg: "#0f172a", border: "#22c55e", icon: "✓" },
  error:   { bg: "#0f172a", border: "#C1272D", icon: "✕" },
  info:    { bg: "#0f172a", border: "#3b82f6", icon: "ⓘ" },
  warning: { bg: "#0f172a", border: "#f59e0b", icon: "⚠" },
};

function ToastItem({ toast, onRemove }: { toast: Toast; onRemove: (id: string) => void }) {
  const v = VARIANT_STYLES[toast.variant];
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const t = setTimeout(() => setVisible(true), 10);
    return () => clearTimeout(t);
  }, []);

  return (
    <div
      role="alert"
      style={{
        display: "flex",
        alignItems: "center",
        gap: "0.75rem",
        padding: "0.875rem 1rem",
        background: v.bg,
        borderLeft: `3px solid ${v.border}`,
        borderRadius: 6,
        boxShadow: "0 8px 32px rgba(0,0,0,0.4)",
        minWidth: 280,
        maxWidth: 400,
        transform: visible && !toast.leaving ? "translateX(0)" : "translateX(120%)",
        opacity: visible && !toast.leaving ? 1 : 0,
        transition: "transform 0.28s cubic-bezier(0.22,1,0.36,1), opacity 0.22s ease",
        cursor: "pointer",
      }}
      onClick={() => onRemove(toast.id)}
    >
      <span style={{ flexShrink: 0, width: 20, height: 20, borderRadius: "50%", background: v.border, color: "#fff", fontSize: 11, fontWeight: 800, display: "flex", alignItems: "center", justifyContent: "center" }}>
        {v.icon}
      </span>
      <span style={{ flex: 1, fontSize: "0.8125rem", fontFamily: "var(--mono, monospace)", color: "#e2e8f0", letterSpacing: "0.01em", lineHeight: 1.4 }}>
        {toast.message}
      </span>
      <button
        onClick={(e) => { e.stopPropagation(); onRemove(toast.id); }}
        style={{ background: "none", border: "none", color: "rgba(255,255,255,0.3)", cursor: "pointer", fontSize: 14, padding: "2px 4px", lineHeight: 1, flexShrink: 0 }}
      >
        ✕
      </button>
    </div>
  );
}

// ── Provider ──────────────────────────────────────────────────────────────────
export function ToastProvider({ children }: { children: ReactNode }) {
  const [toasts, setToasts] = useState<Toast[]>([]);
  const timers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());

  const remove = useCallback((id: string) => {
    setToasts((prev) => prev.map((t) => t.id === id ? { ...t, leaving: true } : t));
    setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), 280);
    const timer = timers.current.get(id);
    if (timer) { clearTimeout(timer); timers.current.delete(id); }
  }, []);

  const toast = useCallback((message: string, variant: ToastVariant = "info", duration = 3500) => {
    const id = `t-${Date.now()}-${Math.random().toString(36).slice(2)}`;
    setToasts((prev) => [...prev.slice(-3), { id, message, variant, duration }]);
    const timer = setTimeout(() => remove(id), duration);
    timers.current.set(id, timer);
  }, [remove]);

  const value: ToastContextValue = {
    toast,
    success: (msg) => toast(msg, "success"),
    error:   (msg) => toast(msg, "error"),
    info:    (msg) => toast(msg, "info"),
    warning: (msg) => toast(msg, "warning"),
  };

  return (
    <ToastContext.Provider value={value}>
      {children}
      {/* Render portal at root */}
      <div
        aria-live="assertive"
        style={{
          position: "fixed",
          bottom: 24,
          right: 24,
          zIndex: 9999,
          display: "flex",
          flexDirection: "column-reverse",
          gap: 8,
          pointerEvents: "none",
        }}
      >
        {toasts.map((t) => (
          <div key={t.id} style={{ pointerEvents: "auto" }}>
            <ToastItem toast={t} onRemove={remove} />
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
}
