"use client"

import * as React from "react"
import { motion, AnimatePresence } from "framer-motion"
import { X, CheckCircle, AlertCircle, Info, AlertTriangle } from "lucide-react"
import { cn } from "@/lib/utils"
import { toastVariants } from "@/lib/animations"

export interface Toast {
  id: string
  title?: string
  description?: string
  type?: "success" | "error" | "warning" | "info"
  duration?: number
  action?: {
    label: string
    onClick: () => void
  }
}

interface ToastProps extends Toast {
  onClose: (id: string) => void
}

const ToastComponent: React.FC<ToastProps> = ({
  id,
  title,
  description,
  type = "info",
  duration = 5000,
  action,
  onClose,
}) => {
  React.useEffect(() => {
    if (duration > 0) {
      const timer = setTimeout(() => {
        onClose(id)
      }, duration)

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

  const getIcon = () => {
    switch (type) {
      case "success":
        return <CheckCircle className="h-5 w-5 text-green-600" />
      case "error":
        return <AlertCircle className="h-5 w-5 text-red-600" />
      case "warning":
        return <AlertTriangle className="h-5 w-5 text-yellow-600" />
      default:
        return <Info className="h-5 w-5 text-blue-600" />
    }
  }

  const getBorderColor = () => {
    switch (type) {
      case "success":
        return "border-l-green-500"
      case "error":
        return "border-l-red-500"
      case "warning":
        return "border-l-yellow-500"
      default:
        return "border-l-blue-500"
    }
  }

  return (
    <motion.div
      variants={toastVariants}
      initial="initial"
      animate="animate"
      exit="exit"
      className={cn(
        "relative flex w-full max-w-sm items-center space-x-4 rounded-md border border-border bg-background p-4 shadow-lg",
        "border-l-4",
        getBorderColor()
      )}
      role="alert"
    >
      <div className="flex-shrink-0">{getIcon()}</div>
      
      <div className="flex-1 space-y-1">
        {title && (
          <div className="text-sm font-semibold text-foreground">{title}</div>
        )}
        {description && (
          <div className="text-sm text-muted-foreground">{description}</div>
        )}
        {action && (
          <button
            onClick={action.onClick}
            className="text-sm font-medium text-primary hover:text-primary/80 underline underline-offset-2"
          >
            {action.label}
          </button>
        )}
      </div>

      <button
        onClick={() => onClose(id)}
        className="flex-shrink-0 rounded-md p-1 text-muted-foreground hover:text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
      >
        <X className="h-4 w-4" />
      </button>
    </motion.div>
  )
}

interface ToastContextType {
  toasts: Toast[]
  addToast: (toast: Omit<Toast, "id">) => void
  removeToast: (id: string) => void
  success: (message: string, options?: Partial<Toast>) => void
  error: (message: string, options?: Partial<Toast>) => void
  warning: (message: string, options?: Partial<Toast>) => void
  info: (message: string, options?: Partial<Toast>) => void
}

const ToastContext = React.createContext<ToastContextType | undefined>(undefined)

export const useToast = () => {
  const context = React.useContext(ToastContext)
  if (!context) {
    throw new Error("useToast must be used within a ToastProvider")
  }
  return context
}

interface ToastProviderProps {
  children: React.ReactNode
}

export const ToastProvider: React.FC<ToastProviderProps> = ({ children }) => {
  const [toasts, setToasts] = React.useState<Toast[]>([])

  const addToast = React.useCallback((toast: Omit<Toast, "id">) => {
    const id = Math.random().toString(36).substr(2, 9)
    setToasts((prev) => [...prev, { ...toast, id }])
  }, [])

  const removeToast = React.useCallback((id: string) => {
    setToasts((prev) => prev.filter((toast) => toast.id !== id))
  }, [])

  const success = React.useCallback(
    (message: string, options?: Partial<Toast>) => {
      addToast({
        type: "success",
        title: "Success",
        description: message,
        ...options,
      })
    },
    [addToast]
  )

  const error = React.useCallback(
    (message: string, options?: Partial<Toast>) => {
      addToast({
        type: "error",
        title: "Error",
        description: message,
        duration: 7000,
        ...options,
      })
    },
    [addToast]
  )

  const warning = React.useCallback(
    (message: string, options?: Partial<Toast>) => {
      addToast({
        type: "warning",
        title: "Warning",
        description: message,
        ...options,
      })
    },
    [addToast]
  )

  const info = React.useCallback(
    (message: string, options?: Partial<Toast>) => {
      addToast({
        type: "info",
        title: "Info",
        description: message,
        ...options,
      })
    },
    [addToast]
  )

  const value = React.useMemo(
    () => ({
      toasts,
      addToast,
      removeToast,
      success,
      error,
      warning,
      info,
    }),
    [toasts, addToast, removeToast, success, error, warning, info]
  )

  return (
    <ToastContext.Provider value={value}>
      {children}
      <div className="fixed top-4 right-4 z-50 flex flex-col space-y-2">
        <AnimatePresence>
          {toasts.map((toast) => (
            <ToastComponent
              key={toast.id}
              {...toast}
              onClose={removeToast}
            />
          ))}
        </AnimatePresence>
      </div>
    </ToastContext.Provider>
  )
}