import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { CheckCircle, Info, AlertTriangle, XCircle } from 'lucide-react';

import { cn } from '../../shared/utils';

const alertVariants = cva(
  'relative w-full rounded-[var(--radius)] border-l-4 px-4 py-3 grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-5 [&>svg]:translate-y-0.5 [&>svg]:text-current',
  {
    variants: {
      variant: {
        default: 'bg-muted/50 border-l-border text-foreground [&>svg]:text-muted-foreground',
        success:
          'bg-[color:var(--success)]/10 dark:bg-[color:var(--success)]/20 border-l-[color:var(--success)] text-foreground [&>svg]:text-[color:var(--success)]',
        info: 'bg-[color:var(--info)]/10 dark:bg-[color:var(--info)]/20 border-l-[color:var(--info)] text-foreground [&>svg]:text-[color:var(--info)]',
        warning:
          'bg-[color:var(--warning)]/10 dark:bg-[color:var(--warning)]/20 border-l-[color:var(--warning)] text-foreground [&>svg]:text-[color:var(--warning)]',
        destructive:
          'bg-[color:var(--destructive)]/10 dark:bg-[color:var(--destructive)]/20 border-l-[color:var(--destructive)] text-foreground [&>svg]:text-[color:var(--destructive)]',
      },
    },
    defaultVariants: {
      variant: 'default',
    },
  }
);

const alertIcons = {
  default: Info,
  success: CheckCircle,
  info: Info,
  warning: AlertTriangle,
  destructive: XCircle,
} as const;

type AlertVariantType = keyof typeof alertIcons;

export interface AlertProps
  extends React.ComponentProps<'div'>, VariantProps<typeof alertVariants> {
  /** Custom icon. If not provided, a default semantic icon for the variant is used. Set to null to hide. */
  icon?: React.ReactNode;
}

/**
 * Inline feedback banner for contextual status messages.
 *
 * @description
 * A non-transient, fixed-in-flow message block for critical validations or
 * contextual warnings. Contains a built-in icon based on the variant
 * (overridable via `icon` prop). Fills 100% of its container width.
 *
 * @ai-rules
 * 1. Always compose with `<AlertTitle>` + `<AlertDescription>` to preserve internal typography hierarchy.
 * 2. For transient feedback (success/error after submit), use `<Toaster>` (Sonner) instead.
 * 3. Available variants: `default`, `success`, `info`, `warning`, `destructive`.
 */
function Alert({ className, variant, icon, children, ...props }: AlertProps) {
  // Determine valid variant with safe fallback
  const alertVariant: AlertVariantType =
    variant && variant in alertIcons ? (variant as AlertVariantType) : 'default';

  const DefaultIcon = alertIcons[alertVariant];

  return (
    <div
      data-slot="alert"
      role="alert"
      className={cn(alertVariants({ variant }), className)}
      {...props}
    >
      {icon !== undefined ? icon : <DefaultIcon className="flex-shrink-0" />}
      <div className="flex-1">{children}</div>
    </div>
  );
}

function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
  return (
    <div
      data-slot="alert-title"
      className={cn('font-medium mb-1 leading-tight', className)}
      {...props}
    />
  );
}

function AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {
  return (
    <div data-slot="alert-description" className={cn('leading-relaxed', className)} {...props} />
  );
}

export { Alert, AlertTitle, AlertDescription };
