<template>
  <div
    :class="[
      'default-select',
      attrs.class,
    ]"
    :style="attrs.style"
  >
    <q-select
      ref="selectRef"
      v-model="model"
      v-bind="selectAttrs"
      class="default-select-field"
      color="secondary"
      dense
      hide-bottom-space
      hide-dropdown-icon
      input-class="default-select-native"
      label-color="secondary"
      lazy-rules="ondemand"
      :bg-color
      :class="[
        inputClass,
        {
          'required-field': required,
        },
      ]"
      :error="!!error"
      :error-message="normalizedErrorMessage"
      :label
      :outlined
      :popup-content-class="popupContentClass"
      :rules
      @update:model-value="error = null"
    >
      <template
        v-for="(_, slotName) in $slots"
        #[slotName]="scope"
      >
        <slot
          :name="slotName"
          v-bind="scope ?? {}"
        />
      </template>

      <template #append>
        <q-icon
          color="secondary"
          :name="dropdownIcon"
        />
      </template>
    </q-select>
  </div>
</template>

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

defineOptions({
  inheritAttrs: false,
});

const {
  bgColor,
  dropdownIcon,
  errorMessage,
  inputClass,
  label,
  outlined,
  popupContentClass,
  rules,
} = defineProps({
  bgColor: {
    type: String,
    default: "white",
  },
  dropdownIcon: {
    type: String,
    default: "mdi-chevron-down",
  },
  errorMessage: {
    type: String,
    default: undefined,
  },
  inputClass: {
    type: String,
    default: null,
  },
  label: {
    type: String,
    default: "",
  },
  outlined: {
    type: Boolean,
    default: false,
  },
  popupContentClass: {
    type: String,
    default: null,
  },
  rules: {
    type: Array,
    default: () => [],
  },
});

const attrs = useAttrs();

const model = defineModel({
  type: [
    String,
    Object,
    Array,
    Number,
    null,
  ],
});

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

const selectRef = ref(null);

const normalizedErrorMessage = computed(() => {
  if (errorMessage != null) {
    return errorMessage;
  }

  if (error.value == null) {
    return void 0;
  }

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

  return String(error.value);
});

const required = computed(() =>
  rules.some(
    (rule) => rule?.$id === "required",
  ),
);

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

  return rest;
});

defineExpose({
  selectRef,
});
</script>

<style scoped>
.default-select {
  min-width: 0;
}

.default-select[class*="col-"] {
  flex-grow: 0;
  flex-shrink: 0;
}

.default-select-field {
  min-width: 0;
  width: 100%;
}

:deep(.default-select-field .q-field__inner),
:deep(.default-select-field .q-field__control),
:deep(.default-select-field .q-field__control-container),
:deep(.default-select-field .q-field__native),
:deep(.default-select-field .q-field__input) {
  min-width: 0;
  max-width: 100%;
}

:deep(.default-select-native) {
  color: var(--q-primary) !important;
  min-width: 0 !important;
  max-width: 100% !important;
  -webkit-text-fill-color: var(--q-primary) !important;
}

:deep(.q-field--outlined.q-field--rounded .q-field__control) {
  border-radius: 8px;
}

:deep(.required-field .q-field__label::after) {
  color: var(--q-negative);
  content: " *";
}
</style>