<template>
  <div class="column" :class="attrs.class" :style="attrs.style">
    <div v-if="label || $slots.label" class="q-pl-xs">
      <slot name="label">
        <span>{{ label }}</span>
      </slot>

      <span v-if="required" class="text-negative q-ml-xs">*</span>
    </div>

    <div class="col">
      <q-select
        ref="selectRef"
        v-model="model"
        v-bind="selectAttrs"
        behavior="menu"
        hide-bottom-space
        hide-dropdown-icon
        multiple
        use-chips
        :bg-color="bgColor"
        :class="inputClass"
        :error="!!error"
        :error-message="errorMessage"
        :popup-content-class="popupContentClass"
        :rules="rules"
        @update:model-value="error = null"
      >
        <template #append>
          <q-icon name="mdi-chevron-down" class="text-text" />
        </template>

        <template #selected-item="scope">
          <q-chip
            class="q-ma-xs"
            dense
            removable
            @remove="scope.removeAtIndex(scope.index)"
          >
            {{ scope.opt?.label ?? scope.opt }}
          </q-chip>
        </template>

        <template v-for="(_, slotName) in $slots" #[slotName]="scope">
          <slot :name="slotName" v-bind="scope" />
        </template>
      </q-select>
    </div>
  </div>
</template>

<script setup>
import { computed, onBeforeMount, ref, useAttrs } from "vue";

defineOptions({
  inheritAttrs: false,
});

const props = defineProps({
  label: { type: String, default: "" },
  rules: { type: Array, default: () => [] },
  inputClass: { type: String, default: null },
  popupContentClass: { type: String, default: null },
  bgColor: { type: String, default: "surface" },
});

const { label, inputClass, popupContentClass, bgColor, rules } = props;

const attrs = useAttrs();

const model = defineModel({
  type: Array,
  default: () => [],
});

const error = defineModel("error", {
  type: [String, Object, Array, Boolean, null],
});

const selectRef = ref(null);
const required = ref(false);

const errorMessage = computed(() => {
  if (error.value == null) return void 0;

  if (typeof error.value === "boolean") return void 0;

  return String(error.value);
});

const selectAttrs = computed(() => {
  // eslint-disable-next-line no-unused-vars
  const { class: _, style: __, ...rest } = attrs;

  return rest;
});

onBeforeMount(() => {
  rules.forEach((r) => {
    if (r?.$id === "required") {
      required.value = true;
    }
  });
});

defineExpose({
  focus: () => {
    if (selectRef.value && typeof selectRef.value.focus === "function") {
      selectRef.value.focus();
    }
  },
});
</script>
