<template>
  <div
    class="flex items-center"
    :class="[disabled ? 'opacity-20' : '']"
  >
    <input
      :id="name"
      type="checkbox"
      class="hidden"
      :checked="isChecked"
      :disabled="disabled"
      :value="value"
      @change="updateInput"
    >
    <label
      v-if="viewType === 'checkbox'"
      :for="name"
      class="flex items-center text-deepblue-900 dark:text-gray-200"
      :class="twMerge(textSizeOptions[size], disabled ? 'cursor-default': 'cursor-pointer', labelClass)"
    >
      <span
        v-if="side==='left' && hasSlotContent"
        class="select-none"
      >
        <slot />
      </span>
      <span :class="[sizeOptions[size]]">
        <a-icon-checkbox-intermediate
          v-if="isIntermediate"
          class="w-full h-full"
          :class="twMerge('text-blue-700 dark:text-blue-500', intermediateCheckboxClass)"
        />
        <a-icon-checkbox-active
          v-else-if="isChecked"
          class="w-full h-full"
          :class="twMerge('text-blue-700 dark:text-blue-500', checkboxClass)"
        />
        <a-icon-checkbox-empty
          v-else
          class="w-full h-full"
          :class="twMerge('text-deepblue-900 dark:text-gray-200', emptyCheckboxClass)"
        />
      </span>
      <span
        v-if="side==='right' && hasSlotContent"
        class="select-none"
      >
        <slot />
      </span>
    </label>
    <label
      v-else-if="viewType === 'chip'"
      :for="name"
      class="px-[10px] py-[3.5px] text-deepblue-900 border border-gray-500 rounded-full  dark:text-gray-200 text-xs"
      :class="[{'bg-blue-700 text-white dark:bg-blue-500 dark:border-blue-500 dark:text-gray-900 font-medium': isChecked}]"
    >
      <slot/>
    </label>
  </div>
</template>

<script setup lang="ts">
import { twMerge } from 'tailwind-merge'


defineOptions({ name: 'ACheckbox' })
const emit = defineEmits(['update:modelValue'])

interface Props {
  size?: 'lg' | 'sm',
  name?: string
  modelValue: string | number | Array<any> | Object | boolean | null
  value?: string | number | Object | null
  intermediate?: boolean
  disabled?: boolean
  side?: 'right' | 'left' | null
  masterControl?: boolean;
  emptyCheckboxClass?: string
  intermediateCheckboxClass?: string
  alwaysIntermediate?: boolean
  checkboxClass?: string
  labelClass?: string
  viewType?: 'checkbox' | 'chip'
}

const props = withDefaults(defineProps<Props>(), {
  size: 'sm',
  name: 'check',
  value: null,
  side: 'left',
  modelValue: () => [],
  masterControl: false,
  emptyCheckboxClass: '',
  intermediateCheckboxClass: '',
  checkboxClass: '',
  labelClass: '',
  viewType: 'checkbox',
  alwaysIntermediate: false
})

const slots = useSlots()

const isChecked = computed(() => {
  if (props.modelValue instanceof Array) {
    return props.modelValue.includes(props.value)
  }
  return props.modelValue === true
})
const isIntermediate = computed(() => {
  if (props.alwaysIntermediate) {
    return props.intermediate
  } else {
    return isChecked.value && props.intermediate
  }
})

const updateInput = (e) => {
  const isChecked = e.target.checked
  if (props.masterControl) {
    emit('update:modelValue', isChecked)
  } else if (props.modelValue instanceof Array) {
    const newValue = [...props.modelValue]
    if (isChecked) {
      newValue.push(props.value)
    } else {
      newValue.splice(newValue.indexOf(props.value), 1)
    }
    emit('update:modelValue', newValue)
  } else {
    emit('update:modelValue', !!isChecked)
  }
}

const sizeOptions = {
  lg: 'min-w-6 min-h-6 max-w-6 max-h-6',
  sm: 'min-w-4 min-h-4 max-w-4 max-h-4'
}
const textSizeOptions = {
  lg: 'text-sm gap-2.5',
  sm: 'text-xs gap-2'
}


const hasSlotContent = computed(() => {
  return !!slots.default?.().length
})

</script>

<style scoped>
</style>
