"use client"

import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"

/* ---------------------------------- Types ---------------------------------- */
const alertVariants = cva("relative w-full rounded-lg border p-4", {
  variants: {
    variant: {
      default: "bg-background text-foreground",
      info: "",
      success: "",
      warning: "",
      error: "",
    },
    size: {
      default: "p-4",
      compact: "p-3",
      large: "p-6",
    },
  },
  defaultVariants: {
    variant: "default",
    size: "default",
  },
})

export interface AlertProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {
  onClose?: () => void
}

/* ---------------------------------- Context ---------------------------------- */
type AlertContextValue = {
  variant: AlertProps["variant"]
  size: AlertProps["size"]
  hasActions: boolean
  setHasActions: React.Dispatch<React.SetStateAction<boolean>>
}

const AlertContext = React.createContext<AlertContextValue | undefined>(undefined)

function useAlertContext() {
  const context = React.useContext(AlertContext)
  if (!context) {
    throw new Error("Alert compound components must be used within an Alert component")
  }
  return context
}

/* ---------------------------------- Components ---------------------------------- */
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
  ({ className, variant = "default", size = "default", onClose, ...props }, ref) => {
    const [hasActions, setHasActions] = React.useState(false)

    // Apply semantic colors for non-default variants
    const semanticStyle =
      variant !== "default"
        ? {
            backgroundColor: `var(--semantic-${variant === "destructive" ? "error" : variant}-bg)`,
            borderColor: `var(--semantic-${variant === "destructive" ? "error" : variant}-border)`,
          }
        : {}

    return (
      <AlertContext.Provider value={{ variant, size, hasActions, setHasActions }}>
        <div
          ref={ref}
          role="alert"
          className={cn(alertVariants({ variant, size }), "flex", className)}
          style={semanticStyle}
          {...props}
        />
      </AlertContext.Provider>
    )
  },
)
Alert.displayName = "Alert"

interface AlertIconProps extends React.HTMLAttributes<HTMLDivElement> {
  icon: React.ReactNode
}

const AlertIcon = ({ icon, className, ...props }: AlertIconProps) => {
  const { variant } = useAlertContext()

  const semanticStyle =
    variant !== "default"
      ? {
          color: `var(--semantic-${variant === "destructive" ? "error" : variant}-text)`,
        }
      : {}

  return (
    <div
      className={cn("h-4 w-4 flex-shrink-0", variant === "default" && "text-foreground", className)}
      style={semanticStyle}
      {...props}
    >
      {icon}
    </div>
  )
}
AlertIcon.displayName = "AlertIcon"

const AlertContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
  ({ className, ...props }, ref) => (
    <div ref={ref} className={cn("ml-3 overflow-hidden flex-1", className)} {...props} />
  ),
)
AlertContent.displayName = "AlertContent"

const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
  ({ className, ...props }, ref) => {
    const { variant } = useAlertContext()

    const semanticStyle =
      variant !== "default"
        ? {
            color: `var(--semantic-${variant === "destructive" ? "error" : variant}-text)`,
          }
        : {}

    return (
      <h5
        ref={ref}
        className={cn("font-medium leading-none", variant === "default" && "text-foreground", className)}
        style={semanticStyle}
        {...props}
      />
    )
  },
)
AlertTitle.displayName = "AlertTitle"

const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
  ({ className, ...props }, ref) => {
    const { variant, hasActions } = useAlertContext()

    const semanticStyle =
      variant !== "default"
        ? {
            color: `var(--semantic-${variant === "destructive" ? "error" : variant}-text)`,
            opacity: 0.8,
          }
        : {}

    return (
      <p
        ref={ref}
        className={cn(
          "text-sm mt-1",
          hasActions ? "mb-0" : "mb-0",
          variant === "default" && "text-muted-foreground",
          className,
        )}
        style={semanticStyle}
        {...props}
      />
    )
  },
)
AlertDescription.displayName = "AlertDescription"

const AlertActions = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
  ({ className, ...props }, ref) => {
    const { setHasActions } = useAlertContext()

    React.useEffect(() => {
      setHasActions(true)
      return () => setHasActions(false)
    }, [setHasActions])

    return <div ref={ref} className={cn("mt-3 flex items-center gap-2", className)} {...props} />
  },
)
AlertActions.displayName = "AlertActions"

export { Alert, AlertIcon, AlertContent, AlertTitle, AlertDescription, AlertActions }
