import { forwardRef } from "react";

import {
  alertDescriptionVariants,
  alertIconVariants,
  alertTitleVariants,
  alertVariants
} from "./alert.variants";
import { cn } from "../lib/cn";
import type { VariantProps } from "../lib/cva";
import { createDataAttributes, createSlot } from "../lib/contracts";

export type AlertProps = React.ComponentPropsWithoutRef<"div"> &
  VariantProps<typeof alertVariants> & {
    icon?: React.ReactNode;
  };

export const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
  {
    children,
    className,
    icon,
    variant = "default",
    ...props
  },
  ref
) {
  const hasIcon = Boolean(icon);

  return (
    <div
      {...props}
      {...createSlot("root")}
      {...createDataAttributes({
        "has-icon": hasIcon,
        variant
      })}
      className={cn(alertVariants({ hasIcon, variant }), className)}
      ref={ref}
      role={props.role ?? "alert"}
    >
      {hasIcon ? <span {...createSlot("icon")} className={alertIconVariants()}>{icon}</span> : null}
      {children}
    </div>
  );
});

export type AlertTitleProps = React.ComponentPropsWithoutRef<"h4">;

export const AlertTitle = forwardRef<HTMLHeadingElement, AlertTitleProps>(function AlertTitle(
  { className, ...props },
  ref
) {
  return (
    <h4
      {...props}
      {...createSlot("label")}
      className={cn(alertTitleVariants(), className)}
      ref={ref}
    />
  );
});

export type AlertDescriptionProps = React.ComponentPropsWithoutRef<"div">;

export const AlertDescription = forwardRef<HTMLDivElement, AlertDescriptionProps>(
  function AlertDescription({ className, ...props }, ref) {
    return (
      <div
        {...props}
        {...createSlot("description")}
        className={cn(alertDescriptionVariants(), className)}
        ref={ref}
      />
    );
  }
);
