<template>
  <label
    :class="[
      {
        '--active': active
      },
      `--${size}`,
    ]"
    class="ui-select"
    aria-label="select"
  >
    <span
      v-if="label"
      class="ui-select__label"
    >
      <UiIcon
        v-if="labelIcon"
        :name="labelIcon.icon"
        :prefix="labelIcon.prefix"
        class="ui-select__label-icon"
        size="16"
      />
      {{ label }}
    </span>
    <span class="ui-select__wrapper">
      <UiIcon
        v-if="icon"
        :name="icon"
        size="16"
        class="ui-select__pre-icon"
      />
      <select
        v-model="proxy"
        :class="{'--icon': icon, '--placeholder': isFirstSelected}"
        :name="name"
        class="ui-select__button"
        required
      >
        <option
          v-if="placeholder"
          class="ui-select__option"
          value=""
          disabled
        >{{ capitalize(placeholder) }}</option>
        <template
          v-for="(item, index) in items"
          :key="`ui-select-${name}-${index}`"
        >
          <hr v-if="separatorBefore !== undefined && item.value === separatorBefore && items.length > 1">
          <option
            :value="item.value"
            class="ui-select__option"
          >{{ capitalize(item.title as string || item.name as string) }}</option>
        </template>
      </select>
      <UiIcon
        class="ui-select__icon"
        name="dropdown"
        size="20"
      />
    </span>
  </label>
</template>

<script setup lang="ts">
import type { ISelectItem } from '../../types';
import { convertString } from '../../runtime';

export interface ISelectLabelIcon {
  icon: string
  prefix?: string
}

export interface ISelectProps {
  name: string
  modelValue: string | undefined
  items: ISelectItem[]
  placeholder?: string
  label?: string
  icon?: string
  labelIcon?: ISelectLabelIcon
  size?: 'm' | 's'
  active?: boolean
  isFirstPlaceholder?: boolean
  separatorBefore?: string
}

const props = withDefaults(defineProps<ISelectProps>(), {
  size: 'm'
});

const emit = defineEmits<{
  (eventName: 'update:modelValue', value: string): void
  (eventName: 'change', value: string): void
}>();

const proxy = computed({
  get: () => props.modelValue ?? '',
  set: (val: string) => {
    emit('update:modelValue', val);
    emit('change', val);
  }
});

const isFirstSelected = computed(() =>
    props.isFirstPlaceholder && props.items[0]?.value === proxy.value
);

function capitalize(text: string) {
  if (!text) return '';
  return convertString().toCapitalize(text);
}
</script>

<style lang="scss">
.ui-select {
  display: flex;
  flex-direction: column;
}

.ui-select__wrapper {
  position: relative;
}

.ui-select__pre-icon,
.ui-select__icon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--select-icon, #{$select-icon});
}

.ui-select__icon {
  right: 16px;
}

.ui-select__pre-icon {
  left: 12px;
}

.ui-select__button {
  @include font-sm;

  border-radius: $radius-xl;
  padding: 10px 32px 10px 12px;
  background: var(--select-bg, #{$select-bg});
  outline: none;
  border: 1px solid var(--select-border, #{$select-border});
  user-select: none;
  box-sizing: border-box;
  appearance: none;
  font-family: inherit;
  color: var(--select-text, #{$select-text});
  cursor: inherit;
  margin: 0;
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-width: 100%;

  @include from-br(sm) {
    cursor: pointer;
  }
}

.ui-select__button::-ms-expand {
  display: none;
}

.ui-select__button:invalid,
.ui-select__button.--placeholder {
  color: var(--select-placeholder, #{$select-placeholder});
}

.ui-select__button.--icon {
  padding-left: 36px;
}

.ui-select__label {
  @include font-sm;

  display: flex;
  flex-wrap: nowrap;
  column-gap: 8px;
  flex-grow: 1;
  align-items: center;
  margin-bottom: 8px;
  color: var(--select-label, #{$select-label});

  &::first-letter {
    text-transform: uppercase;
  }
}

.ui-select__label-icon {
  flex-shrink: 0;
}

.ui-select.--s .ui-select__label {
  margin-bottom: 8px;
  color: var(--select-label-secondary, #{$select-label-secondary});
}

.ui-select.--wide {
  width: 100%;
}

.ui-select.--s .ui-select__button {
  @include from-br(sm) {
    @include font-sm;

    padding: 8px 32px 8px 12px;
    border-color: var(--select-border-secondary, #{$select-border-secondary});
    border-radius: $radius;
  }
}

.ui-select__option {
  background: var(--select-option-bg, #{$select-option-bg});
  color: var(--select-option-text, #{$select-option-text});
}

.ui-select.--active .ui-select__count {
  background-color: var(--select-count-bg--active, #{$select-count-bg--active});
  color: var(--select-count-text--active, #{$select-count-text--active});
}

.ui-select.--active .ui-select__button {
  background-color: var(--select-bg--active, #{$select-bg--active});
  border-color: var(--select-border--active, #{$select-border--active});
}
</style>
