import React, { useEffect, useState } from 'react';
import { clsx } from 'clsx';
import { X, CheckCircle2, AlertCircle, Info, AlertTriangle } from 'lucide-react';
import Button from './Button';

export type ToastType = 'success' | 'error' | 'warning' | 'info';

export interface ToastProps {
  id: string;
  message: string;
  description?: string;
  type?: ToastType;
  duration?: number;
  onClose: (id: string) => void;
  action?: {
    label: string;
    onClick: () => void;
  };
}

const toastIcons = {
  success: CheckCircle2,
  error: AlertCircle,
  warning: AlertTriangle,
  info: Info,
};

const toastStyles = {
  success: 'bg-success/10 border-success/20 text-success-foreground',
  error: 'bg-destructive/10 border-destructive/20 text-destructive-foreground',
  warning: 'bg-warning/10 border-warning/20 text-warning-foreground',
  info: 'bg-primary/10 border-primary/20 text-primary-foreground',
};

/**
 * Individual toast notification
 */
export const Toast = ({
  id,
  message,
  description,
  type = 'info',
  duration = 5000,
  onClose,
  action,
}: ToastProps) => {
  const [isVisible, setIsVisible] = useState(true);

  useEffect(() => {
    if (duration > 0) {
      const timer = setTimeout(() => {
        setIsVisible(false);
        setTimeout(() => onClose(id), 300); // Wait for animation
      }, duration);

      return () => clearTimeout(timer);
    }
  }, [duration, id, onClose]);

  const Icon = toastIcons[type];

  if (!isVisible) return null;

  return (
    <div
      className={clsx(
        'relative flex items-start gap-3 p-4 rounded-lg border shadow-lg',
        'min-w-[300px] max-w-[500px]',
        'animate-in slide-in-from-top-5 fade-in-0 duration-300',
        toastStyles[type]
      )}
      role="alert"
    >
      <Icon className="h-5 w-5 flex-shrink-0 mt-0.5" />
      <div className="flex-1 min-w-0">
        <p className="text-sm font-medium">{message}</p>
        {description && (
          <p className="text-sm mt-1 opacity-90">{description}</p>
        )}
        {action && (
          <div className="mt-3">
            <Button
              variant="outline"
              size="sm"
              onClick={() => {
                action.onClick();
                onClose(id);
              }}
            >
              {action.label}
            </Button>
          </div>
        )}
      </div>
      <button
        type="button"
        onClick={() => {
          setIsVisible(false);
          setTimeout(() => onClose(id), 300);
        }}
        className="flex-shrink-0 rounded-sm opacity-70 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring transition-opacity"
        aria-label="Close"
      >
        <X className="h-4 w-4" />
      </button>
    </div>
  );
};

/**
 * Toast container/provider
 */
export interface ToastContainerProps {
  toasts: ToastProps[];
  onClose: (id: string) => void;
  position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
}

export const ToastContainer = ({
  toasts,
  onClose,
  position = 'top-right',
}: ToastContainerProps) => {
  const positionClasses = {
    'top-right': 'top-4 right-4',
    'top-left': 'top-4 left-4',
    'bottom-right': 'bottom-4 right-4',
    'bottom-left': 'bottom-4 left-4',
    'top-center': 'top-4 left-1/2 -translate-x-1/2',
    'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2',
  };

  if (toasts.length === 0) return null;

  return (
    <div
      className={clsx(
        'fixed z-50 flex flex-col gap-2',
        positionClasses[position]
      )}
      role="region"
      aria-live="polite"
      aria-label="Notifications"
    >
      {toasts.map((toast) => (
        <Toast key={toast.id} {...toast} onClose={onClose} />
      ))}
    </div>
  );
};

/**
 * Hook for managing toasts
 */
export const useToast = () => {
  const [toasts, setToasts] = useState<ToastProps[]>([]);

  const showToast = (
    message: string,
    options?: {
      description?: string;
      type?: ToastType;
      duration?: number;
      action?: { label: string; onClick: () => void };
    }
  ) => {
    const id = `toast-${Date.now()}-${Math.random()}`;
    const newToast: ToastProps = {
      id,
      message,
      description: options?.description,
      type: options?.type || 'info',
      duration: options?.duration ?? 5000,
      onClose: (id) => {
        setToasts((prev) => prev.filter((t) => t.id !== id));
      },
      action: options?.action,
    };

    setToasts((prev) => [...prev, newToast]);
    return id;
  };

  const removeToast = (id: string) => {
    setToasts((prev) => prev.filter((t) => t.id !== id));
  };

  return {
    toasts,
    showToast,
    removeToast,
    success: (message: string, options?: Omit<Parameters<typeof showToast>[1], 'type'>) =>
      showToast(message, { ...options, type: 'success' }),
    error: (message: string, options?: Omit<Parameters<typeof showToast>[1], 'type'>) =>
      showToast(message, { ...options, type: 'error' }),
    warning: (message: string, options?: Omit<Parameters<typeof showToast>[1], 'type'>) =>
      showToast(message, { ...options, type: 'warning' }),
    info: (message: string, options?: Omit<Parameters<typeof showToast>[1], 'type'>) =>
      showToast(message, { ...options, type: 'info' }),
  };
};

