import React from 'react';
import { cva, VariantProps } from 'class-variance-authority';
import { parseUrl } from '../../utils/parseUrl';
import { cssMerge } from '../../utils/cssMerge';
import { IconIds } from '../../molecules/Icon/iconIds';
import { Icon } from '../../molecules/Icon';

const button = cva(
  [
    'tw-justify-center tw-inline-flex tw-items-center tw-gap-3.5',
    'tw-tracking-wider',
    'tw-font-mono',
    'tw-text-center',
    'tw-uppercase',
    'tw-rounded-full',
    'tw-transition-color',
    'tw-w-fit',
    'hover:tw-bg-common-white hover:tw-text-common-black',
    'disabled:tw-bg-gray-500 disabled:tw-text-gray-700 disabled:tw-pointer-events-none disabled:tw-border-common-transparent disabled:tw-bg-none',
  ],
  {
    variants: {
      hierarchy: {
        primary: ['tw-bg-purple-500'],
        secondary: ['tw-bg-green-500', 'tw-text-common-black'],
        tertiary: ['tw-bg-aqua-300', 'tw-text-common-black'],
        outline: ['tw-border', 'tw-border-common-white'],
        purpleGradient: ['tw-bg-gradient-button', 'hover:tw-bg-none'],
        greenGradient: ['tw-bg-gradient-two', 'hover:tw-bg-none', 'tw-text-common-black'],
        link: [
          'disabled:tw-bg-common-transparent',
          'disabled:tw-text-gray-500',
          'hover:tw-bg-common-transparent hover:tw-text-aqua-200',
        ],
      },
      size: {
        sm: ['tw-text-sm tw-py-[6px] tw-px-3'],
        md: ['tw-text-sm tw-py-[10px] tw-px-4'],
        lg: ['tw-text-md tw-py-4 tw-px-[18px]'],
        xl: ['tw-text-md tw-py-5 tw-px-6'],
      },
    },
    defaultVariants: {
      hierarchy: 'primary',
      size: 'md',
    },
    compoundVariants: [
      {
        size: ['lg', 'md', 'sm', 'xl'],
        hierarchy: 'link',
        className: 'tw-p-0',
      },
    ],
  }
);

const iconSizeMap = {
  sm: 14,
  md: 14,
  lg: 16,
  xl: 18,
};

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLAnchorElement | HTMLButtonElement>,
    VariantProps<typeof button> {
  url?: string;
  label?: React.ReactNode;
  startIcon?: IconIds;
  endIcon?: IconIds;
  iconClassName?: string;
  iconSize?: number | string;
}

export const Button = ({
  className,
  hierarchy,
  size,
  url,
  label,
  children,
  startIcon,
  endIcon,
  iconClassName,
  iconSize: iconSizeProp,
  ...props
}: ButtonProps) => {
  const { as, tabIndex: _tabIndex, ...parsedUrl } = parseUrl(url);
  const Component = url ? as : 'button';
  const iconSize = iconSizeProp || iconSizeMap[size || 'md'];

  return (
    <Component className={cssMerge(button({ hierarchy, size, className }))} {...parsedUrl} {...props}>
      {startIcon && <Icon id={startIcon} stroke="currentColor" size={iconSize} className={iconClassName} />}
      {(children || label) && <span className="tw-mt-0.5 tw-leading-none">{children || label}</span>}
      {endIcon && <Icon id={endIcon} stroke="currentColor" size={iconSize} className={iconClassName} />}
    </Component>
  );
};
