<template>
    <div :class="wrapperClass">
        <label
            class="flex items-center gap-2 cursor-pointer text-primary-700"
            :class="labelClass"
        >
            <input
                type="checkbox"
                :checked="checked"
                :disabled="disabled"
                :class="['h-4 w-4 cursor-pointer text-primary-500', inputClass]"
                @change="onChange"
            >
            <span v-if="label">{{ label }}</span>
        </label>
    </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

type CheckboxValue = string | number

const props = withDefaults(
    defineProps<{
        modelValue: boolean | CheckboxValue[]
        value?: CheckboxValue
        label?: string
        disabled?: boolean
        wrapperClass?: string
        labelClass?: string
        inputClass?: string
    }>(),
    {
        value: undefined,
        label: '',
        disabled: false,
        wrapperClass: '',
        labelClass: '',
        inputClass: ''
    }
)

const emit = defineEmits<{
    (event: 'update:modelValue', value: boolean | CheckboxValue[]): void
}>()

const checked = computed(() => {
    if (Array.isArray(props.modelValue)) {
        if (props.value === undefined) {
            return false
        }
        return props.modelValue.includes(props.value)
    }
    return Boolean(props.modelValue)
})

const onChange = (event: Event) => {
    const target = event.target as HTMLInputElement
    if (Array.isArray(props.modelValue)) {
        if (props.value === undefined) {
            emit('update:modelValue', props.modelValue)
            return
        }
        const next = new Set(props.modelValue)
        if (target.checked) {
            next.add(props.value)
        } else {
            next.delete(props.value)
        }
        emit('update:modelValue', Array.from(next))
        return
    }
    emit('update:modelValue', target.checked)
}
</script>
