import { css } from '@tesseract-design/css-utils';

export enum ButtonSize {
  SMALL = 'small',
  MEDIUM = 'medium',
  LARGE = 'large',
}

export enum ButtonVariant {
  OUTLINE = 'outline',
  FILLED = 'filled',
}

export type ButtonBaseArgs = {
  size: ButtonSize,
  block: boolean,
  variant: ButtonVariant,
  border: boolean,
  disabled: boolean,
  compact: boolean,
  menuItem: boolean,
}

const MIN_HEIGHTS: Record<ButtonSize, string> = {
  [ButtonSize.SMALL]: '2.5rem',
  [ButtonSize.MEDIUM]: '3rem',
  [ButtonSize.LARGE]: '4rem',
};

export const Button = ({
  size,
  block,
  variant,
  disabled,
  compact,
}: ButtonBaseArgs): string => css.cx(
  css`
    box-sizing: border-box;
    vertical-align: middle;
    appearance: none;
    font: inherit;
    font-family: var(--font-family-base, sans-serif);
    text-transform: uppercase;
    font-weight: bolder;
    border-radius: 0.25rem;
    justify-content: center;
    align-items: center;
    position: relative;
    border: 0;
    user-select: none;
    text-decoration: none;
    white-space: nowrap;
    line-height: 1;

    & > :first-child::before {
      box-shadow: 0 0 0 0 var(--color-accent, blue);
      transition-property: box-shadow;
      transition-duration: 150ms;
      transition-timing-function: linear;
    }

    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    &::-moz-focus-inner {
      outline: 0;
      border: 0;
    }

    &:focus > :first-child::before {
      box-shadow: 0 0 0 0.375rem var(--color-accent, blue);
    }

    &:disabled > :first-child::before {
      box-shadow: 0 0 0 0 var(--color-accent, blue) !important;
    }
  `,

  css.dynamic({
    'min-height': MIN_HEIGHTS[size],
  }),

  css.if (disabled) (
    css`
      --color-accent: var(--color-primary, blue);
      opacity: 0.5;
      cursor: not-allowed;
    `
  ).else (
    css`
      cursor: pointer;
      &:hover {
        --color-accent: var(--color-hover, blue);
        outline: 0;
      }
  
      &:focus {
        --color-accent: var(--color-hover, blue);
        outline: 0;
      }
  
      &:active {
        --color-accent: var(--color-active, red);
        outline: 0;
      }
  
      &:hover > :first-child::before {
        box-shadow: 0 0 0 0.375rem var(--color-accent, blue);
      }
    `
  ),

  css.if (block) (
    css`
      width: 100%;
      display: flex;
    `
  ).else (
    css`
      display: inline-flex;
    `
  ),

  css.if (compact) (
    css`
      font-stretch: condensed;
      padding: 0 0.5rem;
    `
  ).else(
    css`
      padding: 0 1rem;
    `
  ),

  css.if (variant === ButtonVariant.FILLED) (
    css`
      background-color: var(--color-accent, blue);
      color: var(--color-bg, white) !important;
    `
  ),

  css.if (variant === ButtonVariant.OUTLINE) (
    css`
      background-color: var(--color-bg, white);
      color: var(--color-accent, blue);
    `
  ),
);

export const Border = ({
  border
}: ButtonBaseArgs): string => css.cx(
  css.if (border) (
    css`
      border-color: var(--color-accent, blue);
      box-sizing: border-box;
      display: inline-block;
      border-width: 0.125rem;
      border-style: solid;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      border-radius: inherit;
      pointer-events: none;
      &::before {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        content: '';
        border-radius: 0.125rem;
        opacity: 0.5;
        pointer-events: none;
      }
    `
  ),
);

export const Label = ({
  compact,
  menuItem,
}: ButtonBaseArgs): string => css.cx(
  css`
    display: block;
    flex-grow: 1;
    flex-basis: 0;
    min-width: 0;
  `,

  css.if (compact || menuItem) (
    css`
      text-align: left;
    `
  ).else (
    css`
      text-align: center;
    `
  ),

  css.if (compact) (
    css`
      & ~ :last-child {
        margin-right: -0.5rem;
      }
    `
  ).else (
    css`
      & ~ :last-child {
        margin-right: -1rem;
      }
    `
  ),
);

export const BadgeContainer = ({
  size,
}: ButtonBaseArgs): string => css.cx(
  css`
    width: 2rem;
    text-align: center;
    flex-shrink: 0;
    & + * {
      margin-left: -0.5rem;
    }
  `,
  css.nest('&:last-child')(
    css.dynamic({
      width: MIN_HEIGHTS[size],
    })
  ),
);

export const OverflowText = (): string => css.cx(
  css`
    width: 100%;
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    height: 1.1em;
    line-height: 1;
  `,
);

export const IndicatorWrapper = ({
  size
}: ButtonBaseArgs): string => css.cx(
  css`
    flex-shrink: 0;
    box-sizing: border-box;
    display: grid;
    place-content: center;
    padding: 0 1rem;
    z-index: 1;
    pointer-events: none;
    line-height: 1;
    user-select: none;
  `,
  css.dynamic({
    width: `calc(${MIN_HEIGHTS[size]} * 0.75)`,
    height: MIN_HEIGHTS[size],
  }),
);

export const Indicator = () => css.cx(
  css`
    width: 1.5em;
    height: 1.5em;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  `,
);

export const MainText = () => css.cx(
  css`
    width: 100%;
  `,
);

export const Subtext = () => css.cx(
  css`
    display: block;
    height: 1.1em;
    line-height: 1.1;
    width: 100%;
    font-size: 0.875em;
    text-transform: none;
    font-weight: var(--font-weight-base, normal);
  `,
);
