'use client';

import { createContext, useCallback, useContext, useMemo, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { CheckCircle2, AlertCircle, Info, X } from 'lucide-react';

type ToastVariant = 'success' | 'error' | 'info';

type ToastInput = {
  message: string;
  variant?: ToastVariant;
  duration?: number;
};

type ToastItem = {
  id: number;
  message: string;
  variant: ToastVariant;
};

type ToastContextValue = {
  notify: (input: ToastInput) => void;
  success: (message: string, duration?: number) => void;
  error: (message: string, duration?: number) => void;
  info: (message: string, duration?: number) => void;
};

const ToastContext = createContext<ToastContextValue | null>(null);

const DEFAULT_DURATION = 3500;

const VARIANT_STYLES: Record<
  ToastVariant,
  {
    container: string;
    icon: typeof CheckCircle2;
    iconColor: string;
    iconBg: string;
    close: string;
    text: string;
    shadow: string;
  }
> = {
  success: {
    container: 'border-emerald-500/25 bg-emerald-500/10',
    icon: CheckCircle2,
    iconColor: 'text-emerald-300',
    iconBg: 'bg-emerald-500/15 border border-emerald-500/25',
    close: 'text-emerald-200/80 hover:text-emerald-100 hover:bg-emerald-500/20',
    text: 'text-emerald-50',
    shadow: 'shadow-[0_15px_60px_rgba(16,185,129,0.18)]',
  },
  error: {
    container: 'border-rose-500/30 bg-rose-500/10',
    icon: AlertCircle,
    iconColor: 'text-rose-300',
    iconBg: 'bg-rose-500/15 border border-rose-500/25',
    close: 'text-rose-200/80 hover:text-rose-100 hover:bg-rose-500/20',
    text: 'text-rose-50',
    shadow: 'shadow-[0_15px_60px_rgba(244,63,94,0.18)]',
  },
  info: {
    container: 'border-violet-500/30 bg-violet-500/10',
    icon: Info,
    iconColor: 'text-violet-300',
    iconBg: 'bg-violet-500/15 border border-violet-500/25',
    close: 'text-violet-200/80 hover:text-violet-100 hover:bg-violet-500/20',
    text: 'text-violet-50',
    shadow: 'shadow-[0_15px_60px_rgba(139,92,246,0.18)]',
  },
};

export function ToastProvider({ children }: { children: React.ReactNode }) {
  const [toasts, setToasts] = useState<ToastItem[]>([]);

  const removeToast = useCallback((id: number) => {
    setToasts((prev) => prev.filter((toast) => toast.id !== id));
  }, []);

  const notify = useCallback(
    (input: ToastInput) => {
      const id = Date.now() + Math.floor(Math.random() * 1000);
      const variant = input.variant || 'info';
      setToasts((prev) => [...prev, { id, message: input.message, variant }]);

      const timeout = input.duration ?? DEFAULT_DURATION;
      window.setTimeout(() => removeToast(id), timeout);
    },
    [removeToast]
  );

  const value = useMemo<ToastContextValue>(
    () => ({
      notify,
      success: (message, duration) => notify({ message, variant: 'success', duration }),
      error: (message, duration) => notify({ message, variant: 'error', duration }),
      info: (message, duration) => notify({ message, variant: 'info', duration }),
    }),
    [notify]
  );

  return (
    <ToastContext.Provider value={value}>
      {children}

      <div className="pointer-events-none fixed bottom-4 right-4 z-[200] flex w-[calc(100%-2rem)] max-w-[18rem] flex-col items-end gap-2 sm:w-auto">
        <AnimatePresence initial={false}>
          {toasts.map((toast) => {
            const styles = VARIANT_STYLES[toast.variant];
            const Icon = styles.icon;
            return (
              <motion.div
                key={toast.id}
                layout
                initial={{ opacity: 0, y: 10, scale: 0.98 }}
                animate={{ opacity: 1, y: 0, scale: 1 }}
                exit={{ opacity: 0, y: 8, scale: 0.98 }}
                transition={{ duration: 0.18, ease: 'easeOut' }}
                className={`pointer-events-auto w-full rounded-xl border backdrop-blur-xl ${styles.container} ${styles.shadow}`}
              >
                <div className="grid grid-cols-[1.5rem_minmax(0,1fr)_1.5rem] items-center gap-2 p-2.5">
                  <div className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-md ${styles.iconBg}`}>
                    <Icon className={`h-3.5 w-3.5 ${styles.iconColor}`} />
                  </div>

                  <p className={`min-w-0 text-xs leading-snug break-words ${styles.text}`}>{toast.message}</p>

                  <button
                    type="button"
                    onClick={() => removeToast(toast.id)}
                    className={`inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md transition-colors ${styles.close}`}
                    aria-label="Закрыть уведомление"
                  >
                    <X className="h-3.5 w-3.5" />
                  </button>
                </div>
              </motion.div>
            );
          })}
        </AnimatePresence>
      </div>
    </ToastContext.Provider>
  );
}

export function useToast() {
  const context = useContext(ToastContext);

  if (!context) {
    throw new Error('useToast must be used within ToastProvider');
  }

  return context;
}
