import type { ButtonProps as AriaButtonProps } from 'react-aria-components';
import { Button as AriaButton, composeRenderProps } from 'react-aria-components';

import { tv } from 'tailwind-variants';
import { LoadingSpinnerIcon } from '../icons/LoadingSpinner';

export interface ButtonProps extends AriaButtonProps {
  color?: 'primary' | 'light' | 'green' | 'lightGreen' | 'black' | 'gray' | 'orange' | 'navy' | 'lightNavy';
  size?: 'small' | 'medium' | 'large';
  stopPropagation?: boolean;
}

const button = tv({
  base: 'relative inline-flex items-center justify-center gap-2 border cursor-pointer box-border data-focus-visible:ring-2 ring-offset-2',
  variants: {
    size: {
      small: 'h-6 px-3 text-xs font-medium',
      medium: 'h-9 px-3 text-xs font-medium',
      large: 'min-w-30 h-13 px-5 text-sm font-semibold',
    },
    color: {
      primary: 'text-white bg-primary border-primary disabled:bg-kc-gray-be disabled:border-kc-gray-be ring-primary',
      light:
        'text-primary border-primary bg-primary-tertiary02 disabled:text-kc-gray-99 disabled:bg-kc-gray-eb disabled:border-kc-gray-be ring-primary',
      green:
        'text-white bg-kc-green-main border-kc-green-main disabled:bg-kc-gray-be disabled:border-kc-gray-be ring-kc-green-main',
      lightGreen:
        'text-kc-green-main border-kc-green-main bg-kc-green-tertiary02 disabled:text-kc-gray-99 disabled:bg-kc-gray-eb disabled:border-kc-gray-be ring-kc-green-main',
      black:
        'text-white bg-kc-black-34 border-kc-black-34 disabled:bg-kc-gray-be disabled:border-kc-gray-be ring-kc-black-34',
      gray: 'text-kc-black-34 bg-kc-gray-eb border-kc-black-34 disabled:text-kc-gray-99 disabled:bg-kc-gray-eb disabled:border-kc-gray-be ring-kc-black-34',
      orange:
        'text-kc-orange-main bg-kc-orange-tertiary01 border-kc-orange-main disabled:text-kc-gray-99 disabled:bg-kc-gray-eb disabled:border-kc-gray-be ring-kc-orange-main',
      navy: 'text-white bg-kc-navy-main border-kc-navy-main disabled:bg-kc-gray-be disabled:border-kc-gray-be ring-kc-navy-main',
      lightNavy:
        'text-kc-navy-main border-kc-navy-main bg-kc-navy-tertiary02 disabled:text-kc-gray-99 disabled:bg-kc-gray-eb disabled:border-kc-gray-be ring-kc-navy-main',
    },
    isDisabled: {
      true: 'cursor-not-allowed',
    },
    isPending: {
      true: 'text-transparent cursor-progress',
    },
  },
  compoundVariants: [
    {
      color: 'primary',
      isDisabled: false,
      isPending: false,
      className:
        'hover:border-primary-tertiary hover:bg-primary-tertiary active:bg-primary-secondary active:border-primary-secondary',
    },
    {
      color: 'light',
      isDisabled: false,
      isPending: false,
      className:
        'hover:bg-primary-tertiary01 active:text-primary-secondary active:bg-primary-tertiary01 active:border-primary-secondary',
    },
    {
      color: 'green',
      isDisabled: false,
      isPending: false,
      className:
        'hover:bg-kc-green-tertiary hover:border-kc-green-tertiary active:bg-kc-green-secondary active:border-kc-green-secondary',
    },
    {
      color: 'lightGreen',
      isDisabled: false,
      isPending: false,
      className:
        'hover:bg-kc-green-tertiary01 active:text-kc-green-secondary active:bg-kc-green-tertiary01 active:border-kc-green-secondary',
    },
    {
      color: 'black',
      isDisabled: false,
      isPending: false,
      className: 'hover:bg-kc-black-47 hover:border-kc-black-47 active:bg-kc-black-22 active:border-kc-black-22',
    },
    {
      color: 'gray',
      isDisabled: false,
      isPending: false,
      className:
        'hover:bg-kc-gray-da hover:border-kc-black-47 active:text-kc-black-22 active:bg-kc-gray-da active:border-kc-black-22',
    },
    {
      color: 'orange',
      isDisabled: false,
      isPending: false,
      className:
        'hover:bg-kc-orange-tertiary02 active:text-kc-orange-secondary active:bg-kc-orange-tertiary02 active:border-kc-orange-secondary',
    },
    {
      color: 'navy',
      isDisabled: false,
      isPending: false,
      className:
        'hover:border-kc-navy-tertiary hover:bg-kc-navy-tertiary active:bg-kc-navy-secondary active:border-kc-navy-secondary',
    },
    {
      color: 'lightNavy',
      isDisabled: false,
      isPending: false,
      className:
        'hover:bg-kc-navy-tertiary01 active:text-kc-navy-secondary active:bg-kc-navy-tertiary01 active:border-kc-navy-secondary',
    },
  ],
});

export const Button = (props: ButtonProps) => {
  const {
    className,
    onClick,
    color = 'primary',
    size = 'medium',
    children,
    stopPropagation = false,
    ...restProps
  } = props;

  return (
    <AriaButton
      className={composeRenderProps(className, (className, renderProps) => {
        return button({ ...renderProps, color, size, className });
      })}
      onClick={(e) => {
        if (stopPropagation) {
          e.stopPropagation();
        }
        onClick?.(e);
      }}
      {...restProps}
    >
      {composeRenderProps(children, (children, { isPending }) => (
        <>
          {children}
          {isPending && (
            <span aria-hidden className="flex absolute inset-0 justify-center items-center">
              <LoadingSpinnerIcon className="w-4 h-4 text-white animate-spin" />
            </span>
          )}
        </>
      ))}
    </AriaButton>
  );
};
