import { computed } from 'vue'
import { UBaseButton } from '@/components'
import { genericComponent, propsFactory } from '@/utils'

import { makeVariantProps } from '@/composables/variant'
import { makeSizeProps, Sizes } from '@/composables/size'
import { makeComponentProps } from '@/composables/component'
import { makeTagProps } from '@/composables/tag'
import { makeRouterProps } from '@/composables/router'

import UntitledColorTypes from '@/types/untitledColorTypes'
import ColorName from '@/types/colors'
import ButtonVariant from '@/types/buttonVariants'

interface ButtonColors {
  color: ColorName
  backgroundColor?: ColorName
  borderColor?: ColorName
  variant: ButtonVariant
}

export type UButtonSlots = {
  default: never
}

export const makeUButtonProps = propsFactory(
  {
    loading: {
      type: Boolean,
      default: false,
    },
    type: { type: String, default: UntitledColorTypes.primary },
    disabled: { type: Boolean, default: false },
    destructive: { type: Boolean, default: false },
    prependIcon: String,
    appendIcon: String,
    active: {
      type: Boolean,
      default: undefined,
    },

    ...makeVariantProps(),
    ...makeSizeProps({ size: Sizes.sm }),
    ...makeComponentProps(),
    ...makeTagProps(),
    ...makeRouterProps(),
  },
  'UButton'
)

export const UButton = genericComponent<UButtonSlots>()({
  name: 'UButton',

  props: makeUButtonProps(),

  emits: {
    click: (e: MouseEvent) => true,
  },

  setup(props, { emit, slots, attrs }) {
    const buttonColors = computed<ButtonColors>(() => {
      let buttonColors: ButtonColors = {
        color: 'white',
        backgroundColor: 'primary-600',
        borderColor: 'primary-600',
        variant: ButtonVariant.default,
      }

      switch (props.type) {
        case UntitledColorTypes.primary:
          buttonColors = {
            color: 'white',
            backgroundColor: 'primary-600',
            borderColor: 'primary-600',
            variant: ButtonVariant.default,
          }
          break
        case UntitledColorTypes.secondaryGray:
          buttonColors = {
            color: 'gray-700',
            borderColor: 'gray-300',
            variant: ButtonVariant.outline,
          }
          break
        case UntitledColorTypes.secondaryColor:
          buttonColors = {
            color: 'primary-700',
            borderColor: 'primary-50',
            backgroundColor: 'primary-50',
            variant: ButtonVariant.default,
          }
          break
        case UntitledColorTypes.tertiaryGray:
          buttonColors = {
            color: 'gray-600',
            variant: ButtonVariant.plain,
          }
          break
        case UntitledColorTypes.tertiaryColor:
          buttonColors = {
            color: 'primary-700',
            variant: ButtonVariant.plain,
          }
          break
        case UntitledColorTypes.linkGray:
          buttonColors = {
            color: 'gray-600',
            variant: ButtonVariant.text,
          }
          break
        case UntitledColorTypes.linkColor:
          buttonColors = {
            color: 'primary-700',
            variant: ButtonVariant.text,
          }
          break
        default:
          break
      }

      return buttonColors
    })

    return () => (
      <UBaseButton
        {...props}
        {...attrs}
        v-slots:default={slots.default}
        variant={buttonColors.value.variant}
        color={buttonColors.value.color}
        background-color={buttonColors.value.backgroundColor}
        border-color={buttonColors.value.borderColor}
        onClick={(e: MouseEvent) => emit('click', e)}
      />
    )
  },
})

export type UButton = InstanceType<typeof UButton>
