<template>
  <SelectWrapper
    class="nested-select"
    v-model="state.keyword"
    :selected-item="state.selectedItem"
    v-bind="$props"
    @open="open"
    @close="close"
  >
    <ul class="main" v-show="state.active">
      <li class="search" v-if="props.search">
        <SpaceInput
          label=""
          :placeholder="$t('common.search')"
          v-model="state.keyword"
        >
          <img src="@/assets/icons/actions/search.svg" />
        </SpaceInput>
      </li>
      <li
        class="brr"
        v-for="(item, index) in filteredList"
        :key="index"
        :class="{
          selected: state.mainId === item.id,
          expanded: state.activeNestedList === item.id,
        }"
      >
        <div class="item" @click="clickMain(index)">
          <div class="d-flex align-items-center title">
            <div
              class="icon no-shrink mr-4"
              :class="{ hidden: !hasNestedList(index) }"
            >
              <SpIcon name="chevronDown" />
            </div>
            <p class="h600">{{ item.title }}</p>
          </div>
          <AccordionWrapper
            :active="item.id === state.activeNestedList"
            v-if="hasNestedList(index)"
          >
            <ul class="nested">
              <li
                v-for="(nestedItem, nestedIndex) in item.nestedList"
                :key="nestedIndex"
                @click.stop="selectItem(index, nestedIndex)"
                :class="{ selected: state.nestedId === nestedItem.id }"
              >
                <div class="d-flex align-items-center">
                  <RadioIcon
                    class="mr-4"
                    :active="state.nestedId === nestedItem.id"
                  />
                  <p class="h600">{{ nestedItem.title }}</p>
                </div>
              </li>
            </ul>
          </AccordionWrapper>
        </div>
      </li>
    </ul>
  </SelectWrapper>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  onBeforeMount,
  onMounted,
  PropType,
  reactive,
} from "vue";
import FormMixin from "@/mixins/FormMixin";
import { SelectInterface } from "@/models";

export default defineComponent({
  mixins: [FormMixin],
  props: {
    list: {
      type: Array as PropType<SelectInterface[]>,
      default: [],
    },
    modelValue: {
      default: "",
    },
  },
  setup(props: any, { emit }) {
    const state = reactive<{
      mainId: number | null;
      nestedId: number | null;
      nestedTitle: string | null;
      active: boolean;
      keyword: string;
      selectedItem: {
        title: string;
        imgUrl?: string;
      } | null;
      activeNestedList: any;
    }>({
      mainId: null,
      nestedId: null,
      nestedTitle: null,
      active: false,
      keyword: "",
      selectedItem: null,
      activeNestedList: null,
    });

    const filteredList = computed((): SelectInterface[] => {
      if (state.keyword.length <= 0) {
        return props.list;
      }

      let filteredList = [];

      filteredList = props.list.filter((item: any) =>
        item.title.toLowerCase().includes(state.keyword.toLowerCase())
      );

      for (let i = 0; i < props.list.length; i++) {
        if (
          !props.list[i].title
            .toLowerCase()
            .includes(state.keyword.toLowerCase()) &&
          props.list[i].nestedList
        ) {
          //
          let nestedFilteredList = props.list[i].nestedList.filter(
            (item: any) => {
              return item.title
                .toLowerCase()
                .includes(state.keyword.toLowerCase());
            }
          );

          if (nestedFilteredList.length > 0) {
            filteredList.unshift(Object.assign({}, props.list[i]));
            filteredList[0].nestedList = nestedFilteredList;
          }
        }
      }

      return filteredList.reverse();
    });

    onMounted((): void => {
      if (props.modelValue) {
        const mainItemIndex = props.list.findIndex((item: any) => {
          return item.id === props.modelValue.main;
        });

        if (!mainItemIndex) {
          return;
        }

        const nestedItemIndex = props.list[mainItemIndex].nestedList.findIndex(
          (item: any) => {
            return item.id === props.modelValue.nested;
          }
        );

        if (!nestedItemIndex) {
          return;
        }

        state.selectedItem = {
          title:
            props.list[mainItemIndex].title +
            " - " +
            props.list[mainItemIndex].nestedList[nestedItemIndex].title,
        };
      }
    });
    const hasNestedList = (index: number): boolean => {
      return (
        typeof filteredList.value[index].nestedList !== "undefined" &&
        filteredList.value[index].nestedList.length > 0
      );
    };

    const selectItem = (mainIndex: number, nestedIndex: number): void => {
      state.mainId = filteredList.value[mainIndex].id;
      let fullTitle = filteredList.value[mainIndex].title;

      if (hasNestedList(mainIndex)) {
        let childItem = filteredList.value[mainIndex].nestedList[nestedIndex];
        state.nestedId = childItem.id;
        state.nestedTitle = childItem.title;
      }

      if (state.nestedTitle) {
        fullTitle += ` - ${state.nestedTitle}`;
      }

      state.selectedItem = {
        title: fullTitle,
      };

      emit("update:modelValue", {
        fullTitle: fullTitle,
        main: state.mainId,
        nested: state.nestedId,
      });
    };

    const clickMain = (index: number): void => {
      if (
        filteredList.value[index].nestedList &&
        filteredList.value[index].nestedList.length > 0
      ) {
        if (state.activeNestedList === filteredList.value[index].id) {
          state.activeNestedList = null;
        } else {
          state.activeNestedList = filteredList.value[index].id;
        }
      } else {
        state.mainId = index;
        state.nestedId = null;
        state.nestedTitle = null;
        selectItem(index, null);
      }
    };

    const open = (): void => {
      state.active = true;
    };

    const close = (): void => {
      state.active = false;
      state.keyword = "";
      state.activeNestedList = null;
    };

    return {
      open,
      close,
      props,
      state,
      clickMain,
      selectItem,
      filteredList,
      hasNestedList,
    };
  },
});
</script>

<style lang="scss">
.nested-select {
  ul.main {
    & > li {
      .item {
        flex-direction: column;
        align-items: stretch;
      }

      .icon {
        transition: transform 0.3s ease;
      }

      &.expanded {
        .item {
          background-color: var(--fill-quaternary);

          & > .title {
            color: var(--blue);

            .icon {
              transform: rotate(180deg);

              path {
                fill: var(--blue);
              }
            }
          }
        }
      }
    }
  }

  ul.nested {
    & > li {
      padding: 8px 0 8px 40px;
      margin-left: -16px;
      color: var(--text-color-primary);

      @include screen-lg() {
        margin-left: -24px;
        padding: 12px 0 12px 64px;
      }

      &.selected {
        color: var(--blue);
      }

      &:first-child {
        margin-top: 12px;
      }
    }
  }
}

.nested-transition-enter-active,
.nested-transition-leave-active {
  transition: height 5s;
}
</style>
