<template>
  <SelectWrapper
    class="multi-select"
    :close-on-change="false"
    :selected-item="title"
    :placeholder="props.placeholder"
    :label="props.label"
    :error="props.error"
    :search="false"
    :disabled="props.disabled"
    @open="state.active = true"
    @close="state.active = false"
  >
    <ul v-show="state.active" class="main h600">
      <li v-if="hasSelectAll" class="select-all" @click="selectAll">
        <div class="item">
          <CheckBoxIcon class="mr-4" :active="allSelected" />
          <span>{{ $t("common.selectAll") }}</span>
        </div>
      </li>

      <li
        v-for="(item, index) in list"
        :key="index"
        :class="{ selected: state.selectedItemList.includes(item.id) }"
      >
        <div class="item" @click="selectItem(item.id)">
          <CheckBoxIcon
            class="mr-4"
            :active="state.selectedItemList.includes(item.id)"
          />
          <span>{{ item.title }}</span>
        </div>
      </li>
    </ul>
  </SelectWrapper>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, reactive, watch } from "vue";
import FormMixin from "@/mixins/FormMixin";
import { SelectInterface } from "@/models";
export default defineComponent({
  mixins: [FormMixin],
  props: {
    list: {
      type: Array as PropType<SelectInterface[]>,
      default: [],
    },
    hasSelectAll: {
      type: Boolean,
      default: false,
    },
  },
  setup(props: any, { emit }) {
    const state = reactive<{ active: boolean; selectedItemList: any }>({
      active: false,
      selectedItemList: [],
    });

    const title = computed((): { title: string } => {
      if (state.selectedItemList.length > 0) {
        return {
          title: state.selectedItemList
            .map((id: any) => {
              return props.list.find((item: SelectInterface) => {
                return item.id === id;
              })?.title;
            })
            .join(", "),
        };
      } else {
        return null;
      }
    });

    const allSelected = computed((): boolean => {
      const allSelected = state.selectedItemList.length === props.list.length;
      emit("allSelected", allSelected);
      return allSelected;
    });

    const selectAll = (): void => {
      if (allSelected.value) {
        state.selectedItemList = null;
      } else {
        state.selectedItemList = props.list.map(
          (item: SelectInterface) => item.id
        );
      }
      emit("update:modelValue", state.selectedItemList);
    };

    const selectItem = (id: any) => {
      if (state.selectedItemList.includes(id)) {
        const index = state.selectedItemList.indexOf(id);
        state.selectedItemList.splice(index, 1);
      } else {
        state.selectedItemList.push(id);
      }

      if (state.selectedItemList.length > 0) {
        emit("update:modelValue", state.selectedItemList);
      } else {
        emit("update:modelValue", null);
      }
    };

    watch(
      () => props.modelValue,
      (newVal: any[], oldVal: any[]) => {
        if (props.modelValue) {
          if (newVal !== oldVal) {
            state.selectedItemList = props.modelValue;
          }
        } else {
          state.selectedItemList = [];
        }
      }
    );

    return {
      title,
      state,
      allSelected,
      selectAll,
      selectItem,
      props,
    };
  },
});
</script>
