<script setup>
import { ref, watch, computed } from "vue";
import { VCheckbox } from "vuetify/components/VCheckbox";
import { join, without, filter, head, reject } from "lodash-es";
const props = defineProps({
  items: { type: Array, required: true },
  label: { type: String, required: false },
  modelValue: { type: Array, required: true },
  inline: { type: Boolean, required: false, default: false },
  rules: { type: null, required: false }
});
const emit = defineEmits(["update:modelValue"]);
const values = ref([]);
const valuesOther = ref();
const touched = ref(false);
const onUserInput = () => {
  touched.value = true;
};
const validate = () => {
  touched.value = true;
  return !computedRules.value;
};
const reset = () => {
  touched.value = false;
};
defineExpose({ validate, reset });
const computedRules = computed(() => {
  if (props.rules) {
    let rules = props.rules.map((rule) => rule(values.value.length ? values.value : null));
    rules = without(rules, true);
    return join(rules, ",");
  }
});
const showError = computed(() => touched.value && !!computedRules.value);
const computedOther = computed(() => {
  const itemOther = filter(props.items, { value: "other" });
  return head(itemOther);
});
const computeItems = computed(() => {
  return reject(props.items, { value: "other" });
});
watch(values, () => {
  emit("update:modelValue", [...values.value, valuesOther.value].filter(Boolean));
}, { deep: true });
watch(valuesOther, () => {
  emit("update:modelValue", [...values.value, valuesOther.value].filter(Boolean));
});
watch(props.modelValue, () => {
  if (!props.modelValue) {
    values.value = [];
    valuesOther.value = "";
  } else {
    if (Array.isArray(props.modelValue)) {
      valuesOther.value = props.modelValue.find((item) => !props.items.some(({ value }) => value === item)) || "";
      values.value = props.modelValue.filter((item) => item !== valuesOther.value);
    }
  }
}, { deep: true, immediate: true });
</script>

<template>
  <label class="text-body-1 opacity-60">{{ props.label }}</label>
  <div :class="`d-flex ${inline ? 'flex-row' : 'flex-column'}`">
    <v-checkbox
      v-for="item in computeItems"
      v-model="values"
      :value="item.value"
      density="compact"
      hide-details
      :error="showError"
      :="$attrs"
      :label="item.label"
      @update:model-value="onUserInput"
    />
  </div>
  <v-text-field
    v-if="computedOther"
    v-model="valuesOther"
    hide-details
    :error="showError"
    :="$attrs"
    :label="computedOther.label"
    @update:model-value="onUserInput"
  />
  <label
    v-if="showError"
    class="text-error text-subtitle-2 ml-1"
  >
    {{ computedRules }}
  </label>
</template>
