<template>
  <select :id="fieldId"
          :name="fieldName"
          v-model="model"
          @change="handleChange"
          :required="fieldRequired"
          :disabled="fieldDisabled"
          class="disabled:cursor-not-allowed"
  >
    <option v-if="defaultOption"
            :value="defaultOptionValue"
            :selected="isSelected(defaultOption)"
            :disabled="optionDisabled(defaultOption)"
    >
      {{optionLabel(defaultOption)}}
    </option>

    <slot name="head" />

    <option v-for="opt in options"
           :value="optionValue(opt)"
           :selected="isSelected(opt)"
           :disabled="optionDisabled(opt)"
    >
      {{optionLabel(opt)}}
    </option>

    <slot />
  </select>
</template>

<script setup>
  import {computed, inject, onBeforeMount} from "vue";
  import {useVModel} from '@vueuse/core'
  import {selectProps} from "@/components/select/select-props";
  import {isObject} from "@/util/util";
  import {useInjectedProp} from "@/composables/useInjections";
  import {CONTROL_ID, CONTROL_NAME, CONTROL_REQUIRED, CONTROL_DISABLED} from "@/util/controls";

  const props = defineProps({
    ...selectProps,
  })

  const emit = defineEmits([
    'update:modelValue',
    'load',
    'change'
  ])

  const model = useVModel(props, 'modelValue', emit)
  const valueKey = props.valueKey

  const selectedOption = computed(() => {
    return props.options.find(opt => opt[valueKey] === model.value || opt === model.value)
  })

  const handleChange = () => {
    let eventValue = isObject(selectedOption.value) ? {...selectedOption.value} : model.value
    emit('change', eventValue)
  }

  const defaultOptionValue = computed(() => {
    return isObject(props.defaultOption) ? optionValue(props.defaultOption) : undefined
  })

  const optionValue = (option) => {
    return isObject(option) ? option[valueKey] : option
  }

  const optionLabel = (option) => {
    return isObject(option) ? option[props.labelKey] : option
  }

  const optionDisabled = (option) => {
    return isObject(option) ? option[props.disabledKey] : false
  }

  const isSelected = (option) => {
    let val = isObject(option) ? option[valueKey] : option
    return model.value === val
  }

  onBeforeMount(() => {
    emit('load', selectedOption.value)
  })

  // Injected values will take precedence over prop values
  let fieldId = useInjectedProp(CONTROL_ID, props, 'id')
  let fieldName = useInjectedProp(CONTROL_NAME, props, 'name')
  let fieldDisabled = useInjectedProp(CONTROL_DISABLED, props, 'disabled')
  let fieldRequired = useInjectedProp(CONTROL_REQUIRED, props, 'required')

</script>
