<template>
  <template v-if="to === null">
    <button :class="classes" :type="type">
      <slot />
    </button>
  </template>
  <template v-else>
    <BmsLink :to="to" :target="target" :classes="classes">
      <slot />
    </BmsLink>
  </template>
</template>

<script setup lang="ts">
import { StatusType } from '@/models';
import { computed, useAttrs } from 'vue';
import { RouteLocationRaw } from 'vue-router';
import BmsLink from '@/components/navigation/BmsLink.vue';

interface Props {
  type: 'button' | 'submit';
  to: RouteLocationRaw | null;
  target?: string;
  color: StatusType;
  mode: 'fill' | 'ghost' | 'outline';
  small: boolean;
  icon: boolean;
}

const props = defineProps<Props>();
const attrs = useAttrs();

const classes = computed(() => {
  const disabled = attrs && (!!attrs.disabled || attrs.disabled === '');
  return `bms-button is-${props.color}${
    props.icon ? ' is-icon' : ` bms-button--${props.mode}`
  } ${disabled ? ' bms-button--disabled' : ''} ${props.small ? 'bms-button--small' : ''}`;
});
</script>

<style lang="scss">
@function color($colorName, $colorIntensity: '100') {
  @return #{var(#{'--bms-' + $colorName + '-' + $colorIntensity})};
}

@mixin selectColorsToApply($colorName) {
  &.is-icon {
    --bms-button-background-color: transparent;
    --bms-button-border-color: transparent;
    --bms-button-text-color: var(--bms-font-color);

    --bms-button-hover-background-color: light-dark(
      #{color($colorName, '10')},
      #{color($colorName, '140')}
    );
    --bms-button-hover-border-color: transparent;
    --bms-button-hover-text-color: light-dark(
      #{color($colorName, '140')},
      #{color($colorName, '10')}
    );

    --bms-button-disabled-background-color: transparent;
    --bms-button-disabled-border-color: transparent;
    --bms-button-disabled-text-color: var(--bms-disabled-color);
  }
  &.bms-button--fill {
    --bms-button-background-color: #{color($colorName)};
    --bms-button-border-color: #{color($colorName)};
    --bms-button-text-color: var(--bms-white);

    --bms-button-hover-background-color: #{color($colorName, '140')};
    --bms-button-hover-border-color: #{color($colorName, '140')};
    --bms-button-hover-text-color: var(--bms-white);

    --bms-button-disabled-background-color: var(--bms-disabled-color);
    --bms-button-disabled-border-color: var(--bms-disabled-color);
    --bms-button-disabled-text-color: var(--bms-white);
  }

  &.bms-button--outline {
    --bms-button-background-color: transparent;
    --bms-button-border-color: #{color($colorName)};
    --bms-button-text-color: #{color($colorName)};

    --bms-button-hover-background-color: transparent;
    --bms-button-hover-border-color: light-dark(
      #{color($colorName, '140')},
      #{color($colorName, '75')}
    );
    --bms-button-hover-text-color: light-dark(
      #{color($colorName, '140')},
      #{color($colorName, '10')}
    );

    --bms-button-disabled-background-color: transparent;
    --bms-button-disabled-border-color: var(--bms-disabled-color);
    --bms-button-disabled-text-color: var(--bms-disabled-color);
  }

  &.bms-button--ghost {
    --bms-button-background-color: transparent;
    --bms-button-border-color: transparent;
    --bms-button-text-color: #{color($colorName)};

    --bms-button-hover-background-color: light-dark(
      #{color($colorName, '10')},
      #{color($colorName, '140')}
    );
    --bms-button-hover-border-color: transparent;
    --bms-button-hover-text-color: light-dark(
      #{color($colorName, '140')},
      #{color($colorName, '10')}
    );

    --bms-button-disabled-background-color: transparent;
    --bms-button-disabled-border-color: transparent;
    --bms-button-disabled-text-color: var(--bms-disabled-color);
  }
}

@mixin useColors() {
  background-color: var(--bms-button-background-color);
  border: 1px solid var(--bms-button-border-color);
  color: var(--bms-button-text-color);

  &:focus,
  &:active,
  &:hover,
  &._hover {
    background-color: var(--bms-button-hover-background-color);
    border-color: var(--bms-button-hover-border-color);
    color: var(--bms-button-hover-text-color);
    outline: none;
    text-decoration: none;
  }
  &:disabled,
  &.bms-button--disabled {
    background-color: var(--bms-button-disabled-background-color);
    border-color: var(--bms-button-disabled-border-color);
    color: var(--bms-button-disabled-text-color);
    pointer-events: none;
    cursor: initial;
  }
}

.bms-button {
  font-size: 1em;

  --button-padding: 0.5em;

  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  margin: 0;
  padding: var(--button-padding);
  appearance: none;
  cursor: pointer;
  border-radius: var(--bms-border-radius);
  line-height: 1;
  justify-content: center;
  text-align: center;
  transition:
    transform 0.1s ease-in-out,
    background-color 0.1s linear,
    color 0.1s linear,
    border 0.1s linear;
  text-decoration: none;

  @include useColors();
  @include selectColorsToApply('grey');

  .content {
    margin: 0 var(--button-padding);
  }

  > span {
    &:empty {
      display: none;
    }
  }

  svg {
    display: block;
    width: 1em;
    height: 1em;
  }
  &--small {
    --button-padding: 0.25em;
  }

  &.is-icon {
    padding: var(--button-padding) 0;
  }

  &.is-default {
    @include selectColorsToApply('main');
  }

  &.is-warning {
    @include selectColorsToApply('orange');
  }

  &.is-danger {
    @include selectColorsToApply('red');
  }

  &.is-success {
    @include selectColorsToApply('green');
  }
}
</style>
