<script setup lang="ts">
import { Utils } from '@youcan/ui-core';
import { computed, useSlots } from 'vue';
import type { CheckboxProps } from '~/types';

const props = defineProps<CheckboxProps>();

const emit = defineEmits(['update:modelValue']);
const slots = useSlots();

const model = computed({
  get: () => props.modelValue,
  set: (value: boolean | Array<number | string>) => emit('update:modelValue', value),
});

const checked = computed(
  () => Array.isArray(model.value)
    ? model.value.find(i => i === props.value!)
    : model.value,
);

const idAttr = Utils.uid('checkbox');
const ariaDescribedby = `${idAttr}-aria-describedby`;
</script>

<template>
  <label :for="idAttr" v-bind="$attrs" class="checkbox-content">
    <div class="checkbox" :class="{ 'has-label': slots.label }">
      <input v-bind="$attrs" :id="idAttr" v-model="model" type="checkbox" class="input" :value="value" :aria-describedby="ariaDescribedby">
      <span class="checkmark" :class="{ checked }">
        <i v-if="!$attrs.indeterminate" class="i-youcan-check" />
        <i v-else class="i-youcan-minus" />
      </span>
    </div>
    <div v-if="slots.label" :id="ariaDescribedby" class="label">
      <slot name="label" />
    </div>
  </label>
</template>

<style scoped>
.checkbox-content {
  display: flex;
  align-items: center;
}

.checkbox-content .label {
  display: inline-block;
  flex: 1;
  font: var(--text-sm-regular);
  cursor: pointer;
}

.checkbox-content .checkbox {
  display: block;
  box-sizing: border-box;
  cursor: pointer;
  user-select: none;
}

.checkbox-content .checkbox.has-label {
  margin-inline-end: 8px;
}

.checkbox-content .checkbox .input {
  position: absolute;
  opacity: 0;
}

.checkbox-content .checkbox .checkmark {
  display: grid;
  width: 16px;
  height: 16px;
  border: 1px solid var(--gray-200);
  border-radius: 4px;
  background-color: var(--base-white);
  box-shadow: var(--shadow-xs-gray);
  place-items: center;
}

.checkbox-content .checkbox .checkmark i {
  display: none;
  width: 14px;
  height: 14px;
  color: var(--base-white);
}

.checkbox-content .checkbox .checkmark.checked {
  border: 1px solid transparent;
  background-color: var(--brand-500);
}

.checkbox-content .checkbox .checkmark.checked i {
  display: inline-block;
}

.checkbox-content .checkbox input:disabled ~ .checkmark {
  border: 1px solid var(--gray-200);
  background: var(--base-white);
  box-shadow: none;
  cursor: default;
}

.checkbox-content .checkbox input:enabled:is(:focus, :active) ~ .checkmark {
  box-shadow: var(--focus-shadow-xs-brand);
}

.checkbox-content:hover .checkbox input:enabled ~ .checkmark {
  background-color: var(--gray-50);
}

.checkbox-content .checkbox input:disabled ~ .checkmark.checked {
  background-color: var(--gray-100);
}

.checkbox-content:hover .checkbox input:enabled ~ .checkmark.checked {
  background-color: var(--brand-600);
}

.checkbox-content .checkbox:has(.input:disabled) ~ .label {
  color: var(--gray-300);
}
</style>
