<template>
  <div :class="[getModifiersClass('o-select-list', modifiers), multiple ? 'o-select-list--multiple-select' : '']"
    title="Select list" tabindex="0">
    <span class="o-select-list__trigger js-select-list-trigger">
      <span class="o-select-list__placeholder" :data-placeholder="placeholder"
        :data-placeholder-count-selected="placeholderCountSelected">
        <span v-if="alwaysShowPlaceholder">
          {{ placeholder }}:
        </span>
        <span class="o-select-list__placeholder-text">
          {{
            selectedItems.map((item) => item.text).join(', ') ||
            (alwaysShowPlaceholder ? '' : placeholder)
          }}
        </span>
      </span>
      <span class="o-select-list__trigger-arrow">
      </span>
    </span>
    <div class="o-select-list__menu" role="listbox" tabindex="-1">
      <label v-if="placeholderAllSelected" @click="toggleAll" class="o-select-list__item-all"
        :title="placeholderAllSelected" role="listitem">
        <span class="o-select-list__select-all-text">
          {{ placeholderAllSelected }}
        </span>
      </label>

      <label v-for="(item, index) in options" :key="index" v-on="(checkbox || multiple)
        ? { change: changeValue }
        : { click: () => clickValue(item.value) }
        " class="o-select-list__item" :class="{ 'o-select-list__item--active': item.selected }" :title="item.text"
        role="listitem">
        <span class="o-checkbox">
          <input v-if="checkbox || multiple" type="checkbox" :checked="item.selected" v-model="item.selected" />
          {{ item.text }}
        </span>
      </label>
    </div>
  </div>
</template>

<script setup lang="ts">
// TODO: improve ARIA for select lists
import type { ModifierItems } from './select-list.config';
import { computed } from 'vue';
import useComponentModifiers from '../../composable/useComponentModifiers';
import type { SelectListItem } from './select-list-item';

const props = defineProps<{
  modelValue?: SelectListItem[];
  options?: SelectListItem[]; // If static array is used instead of v-model
  placeholder?: string;
  placeholderAllSelected?: string;
  placeholderCountSelected?: string;
  alwaysShowPlaceholder?: boolean;
  checkbox?: boolean;
  multiple?: boolean;
  modifiers?: ModifierItems;
}>();

const computedOptions = computed({
  get: () => (props.modelValue ?? props.options),
  set: (value) => emit("update:modelValue", value),
})

const selectedItems = computed(() => {
  return computedOptions.value
    .filter((item) => item.selected);
});

const { getModifiersClass } = useComponentModifiers();

const emit = defineEmits<{
  (event: 'change', value: string | string[]): void;
  (event: 'update:modelValue', value: SelectListItem[]): void;
}>();

const toggleAll = () => {
  const allSelected = selectedItems.value.length === computedOptions.value.length;

  computedOptions.value.forEach((item) => {
    item.selected = !allSelected;
  });

  emit('change', computedOptions.value.map((item) => item.value));
};

// runs on select list with single value
const clickValue = (value: string) => {
  computedOptions.value.forEach((item) => {

    item.selected = item.value === value;
  });
  emit('change', value);
};

// runs on select list with multiple select values
const changeValue = () => {
  emit('change', selectedItems.value.map((item) => item.value));
};
</script>
