<template>
  <RawAutocomplete
    v-model="modelValue"
    ref="autocompleteElement"
    :options="optionsLabelValue"
    :open="open"
    :label="label"
    :optional="optional"
    :disabled="disabled"
    :errors="errors"
    :captions="captions"
    :required="required"
    :helperText="helperText"
    :placeholder="placeholder"
    :can-add-new-option="canAddNewOption"
    :small="small"
    :loading="loading"
    @select="(option: any) => emits('select', option)"
    @add-new-option="(newOption: string) => emits('addNewOption', newOption)"
    @input="(e: InputEvent) => emits('input', e)"
  >
    <template #icon-start v-if="currentOptionIcon">
      <span
        class="icon"
        v-if="typeof currentOptionIcon === 'string'"
        v-html="currentOptionIcon"
      ></span>
      <component v-else :is="currentOptionIcon" />
    </template>
    <template #option="{ option }: { option: any }">
      <template v-if="option.icon">
        <span
          class="icon datalist-icon"
          v-if="typeof option.icon === 'string'"
          v-html="option.icon"
        ></span>

        <component class="icon datalist-icon" v-else :is="option.icon" />
      </template>
      {{ option.label }}
    </template>
  </RawAutocomplete>
</template>

<script setup lang="ts">
import { computed, useTemplateRef } from 'vue';
import RawAutocomplete from './RawAutocomplete.vue';
import { InputOption } from '@/models';
import { FieldComponentProps } from '@/plugins/field/field-component.model';

export interface Props extends FieldComponentProps {
  options: string[] | InputOption[];
  modelValue?: string;
  placeholder?: string;
  open?: boolean;
  canAddNewOption?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  open: false,
});

const modelValue = defineModel<string>('modelValue', {
  default: null,
});

const emits = defineEmits<{
  addNewOption: [newOption: string];
  select: [option: InputOption];
  input: [e: InputEvent];
}>();

const autocompleteElement = useTemplateRef('autocompleteElement');

const currentOptionIcon = computed(() => {
  const option = props.options.find(
    (o) => typeof o !== 'string' && o.value === modelValue.value,
  );
  if (!option || typeof option === 'string') return undefined;
  return option.icon;
});

const optionsLabelValue = computed(() =>
  Array.isArray(props.options) &&
  !!props.options.length &&
  typeof props.options[0] === 'string'
    ? props.options.map((o) => ({ label: o, value: o }) as InputOption)
    : (props.options as InputOption[]),
);

defineExpose({
  setFocus: () => autocompleteElement.value?.setFocus(),
});
</script>

<style scoped lang="scss">
.icon {
  height: 1em;
  width: 1em;

  &.datalist-icon {
    margin: 0 0.5em;
  }

  :deep(svg) {
    height: 100%;
    width: 100%;

    * {
      fill: currentColor !important;
    }
  }
}
</style>
