import { cva, VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn, ComponentAnatomy, defineStyleAnatomy } from '../core/styling';

/* -------------------------------------------------------------------------------------------------
 * Anatomy
 * -----------------------------------------------------------------------------------------------*/

export const AlertAnatomy = defineStyleAnatomy({
  root: cva(
    ['UI-Alert__root', 'py-3 px-4 flex justify-between rounded-[--radius]'],
    {
      variants: {
        intent: {
          info: 'bg-blue-50 text-blue-500 dark:bg-opacity-10 dark:text-blue-200',
          success:
            'bg-green-50 text-green-500 dark:bg-opacity-10 dark:text-green-200',
          warning:
            'bg-orange-50 text-orange-500 dark:bg-opacity-10 dark:text-orange-200',
          alert: 'bg-red-50 text-red-500 dark:bg-opacity-10 dark:text-red-200',
          'info-basic':
            'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200',
          'success-basic':
            'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200',
          'warning-basic':
            'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200',
          'alert-basic':
            'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200',
        },
      },
      defaultVariants: {
        intent: 'info',
      },
    }
  ),
  detailsContainer: cva(['UI-Alert__detailsContainer', 'flex']),
  textContainer: cva([
    'UI-Alert__textContainer',
    'flex flex-col self-center ml-3 gap-.5',
  ]),
  title: cva(['UI-Alert__title', 'font-bold']),
  description: cva(['UI-Alert__description']),
  icon: cva(['UI-Alert__icon', 'text-2xl content-evenly'], {
    variants: {
      intent: {
        'info-basic': 'text-blue-500',
        'success-basic': 'text-green-500',
        'warning-basic': 'text-orange-500',
        'alert-basic': 'text-red-500',
        info: 'text-blue-500',
        success: 'text-green-500',
        warning: 'text-orange-500',
        alert: 'text-red-500',
      },
    },
    defaultVariants: {
      intent: 'info-basic',
    },
  }),
  closeButton: cva([
    'UI-Alert__closeButton',
    'flex-none self-start text-2xl hover:opacity-50 transition ease-in cursor-pointer h-5 w-5',
  ]),
});

/* -------------------------------------------------------------------------------------------------
 * Alert
 * -----------------------------------------------------------------------------------------------*/

export type AlertProps = React.ComponentPropsWithRef<'div'> &
  VariantProps<typeof AlertAnatomy.root> &
  ComponentAnatomy<typeof AlertAnatomy> & {
    /**
     * The title of the alert
     */
    title?: string;
    /**
     * The description text or content of the alert
     */
    description?: React.ReactNode;
    /**
     * Replace the default icon with a custom icon
     *
     * - `iconClass` does not apply to custom icons
     */
    icon?: React.ReactNode;
    /**
     * If true, a close button will be rendered
     */
    isClosable?: boolean;
    /**
     * Callback invoked when the close button is clicked
     */
    onClose?: () => void;
  };

export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
  (props, ref) => {
    const {
      children,
      className,
      title,
      description,
      isClosable,
      onClose,
      intent = 'info-basic',
      iconClass,
      detailsContainerClass,
      textContainerClass,
      titleClass,
      descriptionClass,
      closeButtonClass,
      icon,
      ...rest
    } = props;

    let Icon: any = null;

    if (intent === 'info-basic' || intent === 'info') {
      Icon = (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <circle cx="12" cy="12" r="10"></circle>
          <path d="M12 16v-4"></path>
          <path d="M12 8h.01"></path>
        </svg>
      );
    } else if (intent === 'alert-basic' || intent === 'alert') {
      Icon = (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <circle cx="12" cy="12" r="10"></circle>
          <line x1="12" x2="12" y1="8" y2="12"></line>
          <line x1="12" x2="12.01" y1="16" y2="16"></line>
        </svg>
      );
    } else if (intent === 'warning-basic' || intent === 'warning') {
      Icon = (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path>
          <line x1="12" x2="12" y1="9" y2="13"></line>
          <line x1="12" x2="12.01" y1="17" y2="17"></line>
        </svg>
      );
    } else if (intent === 'success-basic' || intent === 'success') {
      Icon = (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"></path>
          <path d="m9 12 2 2 4-4"></path>
        </svg>
      );
    }

    return (
      <div
        className={cn(AlertAnatomy.root({ intent }), className)}
        {...rest}
        ref={ref}
      >
        <div
          className={cn(AlertAnatomy.detailsContainer(), detailsContainerClass)}
        >
          {icon ? (
            icon
          ) : (
            <div
              className={cn(AlertAnatomy.icon({ intent: intent }), iconClass)}
            >
              {Icon && Icon}
            </div>
          )}
          <div className={cn(AlertAnatomy.textContainer(), textContainerClass)}>
            <span className={cn(AlertAnatomy.title(), titleClass)}>
              {title}
            </span>
            {!!(description || children) && (
              <div className={cn(AlertAnatomy.description(), descriptionClass)}>
                {description || children}
              </div>
            )}
          </div>
        </div>
        {onClose && (
          <button
            className={cn(AlertAnatomy.closeButton(), closeButtonClass)}
            onClick={onClose}
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <line x1="18" x2="6" y1="6" y2="18"></line>
              <line x1="6" x2="18" y1="6" y2="18"></line>
            </svg>
          </button>
        )}
      </div>
    );
  }
);

Alert.displayName = 'Alert';
