<script setup lang="ts">
import Select from 'primevue/select';
import type IVSelect from './IVSelect.type.js';
import { useId, computed, watch, ref } from 'vue';
import VLabel from '../label/VLabel.vue';
import VHint from '../hint/VHint.vue';
import styles from '@visua/typography.module.css';

defineOptions({
  inheritAttrs: false,
})

const props = withDefaults(defineProps<IVSelect>(), {
  hint: '',
  successMessage: '',
  errorMessage: '',
  selectId: () => `select-${useId()}`,
  label: '',
  required: false,
  disabled: false,
  options: undefined,
  name: '',
  defaultUnselectedText: 'Sélectionner une option',
  filter: false,
  editable: false,
  optionLabel: undefined,
  optionValue: undefined,
  filterMessage: 'Les résultats sont disponibles',
  selectionMessage: 'Elements sélectionnés',
  emptySelectionMessage: 'Aucun élément sélectionné',
  emptyFilterMessage: 'Aucun résultat trouvé',
  emptyMessage: 'Aucune option disponible',
  optionTemplate: false,

})

const emit = defineEmits([
  'update:modelValue',
  'value-change',
  'change',
  'focus',
  'blur',
  'before-show',
  'before-hide',
  'show',
  'hide',
  'filter',
])

const localModelValue = ref(props.modelValue);
watch(() => props.modelValue, (newVal) => {
  if(localModelValue.value !== newVal){
    localModelValue.value = newVal;
  }
})
watch(localModelValue, (newVal) => {
  if(props.modelValue !== newVal){
    emit('update:modelValue', newVal);
  }
});

const message = computed(() => {
  return props.errorMessage || props.successMessage
})
const messageState = computed(() => {
  return props.errorMessage ? 'error' : 'valid'
})

const typeMessage = computed(() => {
  if (props.errorMessage) return 'alert';
  else if (props.successMessage) return 'success';
  else return undefined;
});

const labelState = computed(() => {
  if(!props.errorMessage && !props.successMessage && !props.disabled) return 'default';
  else if(!props.errorMessage && props.successMessage && !props.disabled) return 'success';
  else if(props.errorMessage && !props.successMessage && !props.disabled) return 'error';
  else return undefined
})
</script>

<template>
  <div class="main-container">
    <VLabel
      v-if="props.label"
      :for="props.selectId"
      :label="props.label"
      :required="!props.disabled"
      :disabled="props.disabled"
      :type="labelState"
      :hint="props.hint"
    >
      <template #required-type v-if="props.required">
        <slot name="required-type"/>
      </template>
    </VLabel>
    <Select
      :name="props.name || props.selectId"
      :options="props.options"
      :optionLabel="props.optionLabel"
      :optionValue="props.optionValue"
      :disabled="props.disabled"
      :aria-disabled="props.disabled"
      :filter="props.filter"
      :editable="props.editable"
      :placeholder="props.placeholder"
      :filter-message="props.filterMessage"
      :selection-message="props.selectionMessage"
      :empty-selection-message="props.emptySelectionMessage"
      :empty-filter-message="props.emptyFilterMessage"
      :empty-message="props.emptyMessage"
      :show-clear="props.showClear"
      :filter-fields="props.filterFields"
      :filter-icon="props.filterIcon"
      :filter-locale="props.filterLocale"
      :filter-match-mode="props.filterMatchMode"
      :filter-placeholder="props.filterPlaceholder"
      :scroll-height="props.scrollHeight"
      :data-key="props.dataKey"
      :loading="props.loading"
      v-bind="$attrs"
      v-model:model-value="localModelValue"
      @update:model-value="emit('update:modelValue', $event)"
      @change="emit('change', $event)"
      @blur="emit('blur', $event)"
      @focus="emit('focus', $event)"
      @value-change="emit('value-change', $event)"
      @before-hide="emit('before-hide', $event)"
      @before-show="emit('before-show', $event)"
      @show="emit('show', $event)"
      @hide="emit('hide', $event)"
      @filter="emit('filter', $event)"
      class="p-select"
      :class="[
        styles['text-body-MD-standard-text-Regular'],
        {
          'disabled': props.disabled,
          'error': props.errorMessage && !props.successMessage && !props.disabled,
          'success': !props.errorMessage && props.successMessage && !props.disabled,
        }
      ]"
    >
      <template v-if="props.optionTemplate" #option="{option, selected, index}">
        <slot name="option" :option="option" :selected="selected" :index="index"/>
      </template>
    </Select>
    <div
      :id="`select-${messageState}-desc-${messageState}`"
      role="alert"
      aria-live="assertive"
    >
      <VHint :title="message" :type="typeMessage" icon/>
    </div>
  </div>
</template>

<style lang="css" scoped>
.main-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: 0.5rem;
}

.p-select{
  width: 100%;
  height: 2.5rem;
}

.p-select.disabled{
  --p-select-border-color: var(--border-disabled-grey);
  --p-select-dropdown-color: var(--text-disabled-grey);
}

.p-select.error{
  --p-select-border-color: var(--border-plain-error);
  --p-select-hover-border-color: var(--border-plain-error);
  --p-select-focus-border-color: var(--border-plain-error);
}
.p-select.success{
  --p-select-border-color: var(--border-plain-success);
  --p-select-hover-border-color: var(--border-plain-success);
  --p-select-focus-border-color: var(--border-plain-success);
}
</style>
