<script lang="ts" setup>
// TODO: refactor Ilkham
import { twJoin, twMerge } from 'tailwind-merge'
import type { Component } from 'vue'
import type { DisabledViewSwitchValues, SizeSwitchValues, ViewSwitchValues } from './types'
import { NuxtLinkLocale} from '#components'

defineOptions({ name: 'AButton' })

interface Props {
  variant?: 'primary' | 'success' | 'danger' | 'gray' | 'ghost'
  view?: 'default' | 'outline' | 'transparent' | 'rounded'
  size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
  form?: 'icon' | 'button'
  icon?: Component
  iconClass?: string
  loading?: boolean
  disabled?: boolean
  block?: boolean
  active?: boolean
  to?: string
}

const props = withDefaults(defineProps<Props>(), {
  variant: 'primary',
  view: 'default',
  size: 'lg',
  form: 'button',
  loading: false,
  disabled: false,
  block: false,
  active: false,
  iconClass: '',
  to: ''
})

const classes = computed(() => [
  'body-600 rounded-md cursor-pointer outline-none transition duration-200 select-none',
  props.block ? 'w-full' : '',
  typeSwitchValues[props.view][props.variant],
  sizeSwitchValues[props.form][props.size]
])
const disabledClasses = computed(() => [
  'body-600 rounded-md outline-none transition duration-200 select-none',
  props.block ? 'w-full' : '',
  disabledTypeSwitchValues[props.view],
  sizeSwitchValues[props.form][props.size]
])

const typeSwitchActiveValues: ViewSwitchValues = {
  default: {
    primary: 'bg-deepblue-900 text-white dark:bg-gray-200',
    success: 'bg-deepblue-900 text-white dark:bg-gray-200',
    danger: 'bg-deepblue-900 text-white dark:bg-gray-200 ',
    gray: 'bg-deepblue-900 text-white dark:bg-gray-200 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200',
    ghost:
      'bg-deepblue-900 text-white dark:bg-gray-200 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200'
  },
  transparent: {
    primary: 'bg-blue-700 text-white dark:bg-blue-500 dark:text-gray-900',
    success: 'bg-green-500 text-white dark:bg-green-400 dark:text-gray-900',
    danger: 'bg-red-500 text-white dark:bg-red-400 dark:text-gray-900',
    gray: 'bg-deepblue-900 text-white dark:bg-gray-200 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200',
    ghost:
      'bg-white text-deepblue-900 dark:bg-gray-900 dark:text-gray-200 hover:text-deepblue-900 dark:hover:text-gray-200'
  },
  outline: {
    primary: 'bg-blue-700 text-white dark:bg-blue-500 dark:text-gray-900',
    success: 'bg-green-500 text-white dark:bg-green-400 dark:text-gray-900',
    danger: 'bg-red-500 text-white dark:bg-red-400 dark:text-gray-900',
    gray: 'bg-deepblue-900 text-white dark:bg-gray-200 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200',
    ghost:
      'bg-gray-500 text-white dark:bg-gray-500 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200'
  },
  rounded: {
    primary: 'bg-deepblue-900 text-white dark:bg-gray-200',
    success: 'bg-deepblue-900 text-white dark:bg-gray-200',
    danger: 'bg-deepblue-900 text-white dark:bg-gray-200 ',
    gray: 'bg-deepblue-900 text-white dark:bg-gray-200 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200',
    ghost:
      'bg-deepblue-900 text-white dark:bg-gray-200 dark:text-gray-900 hover:text-deepblue-900 dark:hover:text-gray-200'
  },
}

const typeSwitchValues: ViewSwitchValues = {
  default: {
    primary:
      'bg-blue-700 text-white hover:bg-blue-900 active:bg-deepblue-900 active:text-white dark:bg-blue-500 dark:text-gray-900 dark:hover:bg-blue-700 dark:active:bg-gray-200',
    success:
      'bg-green-500 text-white hover:bg-green-900 active:bg-deepblue-900 active:text-white dark:bg-green dark:text-gray-900 dark:hover:bg-green-300 dark:active:bg-gray-200',
    danger:
      'bg-red-500 text-white hover:bg-red-700 active:bg-deepblue-900 active:text-white dark:bg-red-400 dark:text-gray-900 dark:hover:bg-red-300 dark:active:bg-gray-200',
    gray: 'bg-deepblue-900/5 text-deepblue-900 hover:bg-deepblue-900/10 active:bg-deepblue-900 active:text-white dark:bg-gray-200/5 dark:hover:bg-gray-200/10 dark:active:bg-gray-200 dark:text-gray-200 dark:active:text-gray-900',
    ghost:
      'bg-white text-deepblue-900 hover:bg-deepblue-900/5 active:bg-deepblue-900 active:text-white dark:bg-gray-900 dark:text-gray-200 dark:bg-gray-900 dark:hover:bg-gray-200/5 dark:active:bg-gray-200 dark:active:text-gray-900'
  },
  transparent: {
    primary:
      'text-blue-700 hover:bg-blue-100 active:bg-blue-700 active:text-white dark:text-blue-500 dark:hover:bg-blue-500/20 dark:active:bg-blue-500 dark:active:text-gray-900',
    success:
      'text-green-500 hover:bg-green-500/20 active:bg-green-500 active:text-white dark:text-green-400 dark:hover:bg-green-400/20 dark:active:bg-green-400 dark:active:text-gray-900',
    danger:
      'text-red-500 hover:bg-red-500/20 active:bg-red-500 active:text-white dark:text-red-400 dark:hover:bg-red-400/20 dark:active:bg-red-400 dark:active:text-gray-900',
    gray: 'text-deepblue-900 hover:bg-deepblue-900/10 active:bg-deepblue-900 active:text-white dark:text-gray-200 dark:hover:bg-gray-200/5 dark:active:bg-gray-200 dark:active:text-gray-900',
    ghost:
      'text-white hover:bg-deepblue-900/10 active:bg-white active:text-deepblue-900 dark:text-gray-200 dark:hover:bg-gray-200/5 dark:active:bg-gray-900 dark:active:text-gray-200'
  },
  outline: {
    primary:
      'border border-blue-700 text-blue-700 hover:bg-blue-100 active:bg-blue-700 active:text-white dark:border-blue-500 dark:text-blue-500 dark:hover:bg-blue-500/20 dark:active:bg-blue-500 dark:active:text-gray-900',
    success:
      'border border-green-500 text-green-500 hover:bg-green-500/20 active:bg-green-500 active:text-white dark:border-green-400 dark:text-green-400 dark:hover:bg-green-400/20 dark:active:bg-green-400 dark:active:text-gray-900',
    danger:
      'border border-red-500 text-red-500 hover:bg-red-500/20 active:bg-red-500 active:text-white dark:text-red-400 dark:border-red-400 dark:hover:bg-red-400/20 dark:active:bg-red-400 dark:active:text-gray-900',
    gray: 'border border-gray-500/50 text-deepblue-900 hover:bg-deepblue-900/10 active:bg-deepblue-900 active:text-white dark:border-gray-500/50 dark:text-gray-200 dark:hover:bg-gray-200/5 dark:active:bg-gray-200 dark:active:text-gray-900',
    ghost:
      'border border-white text-white hover:bg-deepblue-900 active:bg-gray-500 active:text-white dark:border-gray-200 dark:text-gray-200 dark:hover:bg-gray-200/5 dark:active:bg-gray-500 dark:active:text-gray-900'
  },
  rounded: {
    primary:
      'rounded-[32px] bg-blue-700 text-white hover:bg-blue-900 active:bg-deepblue-900 active:text-white dark:bg-blue-500 dark:text-gray-900 dark:hover:bg-blue-700 dark:active:bg-gray-200',
    success:
      'rounded-[32px] bg-green-500 text-white hover:bg-green-900 active:bg-deepblue-900 active:text-white dark:bg-green dark:text-gray-900 dark:hover:bg-green-300 dark:active:bg-gray-200',
    danger:
      'rounded-[32px] bg-red-500 text-white hover:bg-red-700 active:bg-deepblue-900 active:text-white dark:bg-red-400 dark:text-gray-900 dark:hover:bg-red-300 dark:active:bg-gray-200',
    gray: 'rounded-[32px] bg-deepblue-900/5 text-deepblue-900 hover:bg-deepblue-900/10 active:bg-deepblue-900 active:text-white dark:bg-gray-200/5 dark:hover:bg-gray-200/10 dark:active:bg-gray-200 dark:text-gray-200 dark:active:text-gray-900',
    ghost:
      'rounded-[32px] bg-white text-deepblue-900 hover:bg-deepblue-900/5 active:bg-deepblue-900 active:text-white dark:bg-gray-900 dark:text-gray-200 dark:bg-gray-900 dark:hover:bg-gray-200/5 dark:active:bg-gray-200 dark:active:text-gray-900'
  },
}

const disabledTypeSwitchValues: DisabledViewSwitchValues = {
  default:
    'bg-deepblue-900/5 text-deepblue-900/20 dark:bg-gray-200/5 dark:text-gray-200/20 pointer-events-none',
  transparent: 'text-gray-500/50 pointer-events-none',
  outline: 'border border-gray-500/50 text-gray-500/50 pointer-events-none'
}

const sizeSwitchValues: SizeSwitchValues = {
  icon: {
    sm: 'p-1 text-base',
    md: 'p-2 text-base',
    lg: 'p-2 text-2xl',
    xl: 'p-4 text-3xl',
  },
  button: {
    sm: 'px-4 py-1.5 leading-4 !h-[28px]',
    md: 'px-4 py-1.5 !h-[32px]',
    lg: 'px-4 py-2.5',
    xl: 'px-8 py-2.5',
    '2xl': 'px-6 py-[14px] text-xl',
  }
}

const buttonClasses = computed(() =>
  twMerge(
    twJoin(
      props.disabled ? disabledClasses.value : classes.value,
      props.active ? typeSwitchActiveValues[props.view][props.variant] : '',
      props.to ? 'inline-block' : ''
    )
  )
)
</script>
<template>
  <component
    :is="to ? NuxtLinkLocale : 'button'"
    :class="[buttonClasses, 'relative h-fit transition flex items-center justify-center']"
    :disabled="disabled"
    :to="to"
  >
    <span
      :class="[
        { 'opacity-0': loading },
        'flex items-center justify-center gap-2 whitespace-nowrap'
      ]"
    >
      <component :is="icon" :class="[`${iconClass}`]" />
      <slot />
    </span>
    <span
      v-if="loading"
      class="absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center justify-center"
    >
      <a-icon-loader-circle  class="animate-spin"/>
    </span>
  </component>
</template>
