<script setup lang="ts">
import type { MeaningVo, SelectedListType, Word } from './interfaces/index'

import {
  addWords,
  getTopiclList,
  getVocabularyWordList,
  getVocabularyWordListByPrefix,
  getWordClassList,
  updateWords,
} from '#/api'

import Popover from './components/Popover.vue'
import useAutocomplete from './hooks/useAutocomplete'
import useInfiniteScroll from './hooks/useInfiniteScroll'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  diaData: {
    type: Object,
    default: () => ({}),
  },
})
const emits = defineEmits(['update:modelValue', 'onRefresh'])

const show = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    emits('update:modelValue', val)
  },
})

const _formData = {
  id: null,
  levelNum: '',
  stageId: '',
  status: 0,
}
const formData = reactive<Record<string, any>>({
  ..._formData,
})

function onOpen() {
  onClear()
  if (props.diaData.id) {
    for (const i in formData) {
      formData[i] = props.diaData[i]
    }
    selectedList.value = [...props.diaData.wordVoList]
  }

  getWordList()
}

function handleSave() {
  const wordList = selectedList.value.map((_) => {
    return {
      spell: _.spell,
      wordId: _.wordId,
      meaningId: _.meaningId,
    }
  })
  if (props.diaData.id) {
    // 编辑
    updateWords({
      id: props.diaData.id,
      type: 3,
      wordList,
    })
      .then(() => {
        show.value = false
        onClear()
        emits('onRefresh')
      })
      .catch(() => {
        show.value = false
        onClear()
      })

    return
  }
  addWords({
    type: 3,
    wordList,
  })
    .then(() => {
      show.value = false
      onClear()
      emits('onRefresh')
    })
    .catch(() => {
      show.value = false
      onClear()
    })
}

function onClear() {
  // Object.assign(formData, _formData);
  stage.value = stageList.value[0].name
  topicId.value = topicList.value[0].id
  selectedList.value = []
  wordsList.value = []
  globalSeachStr.value = ''
  globalList.value = []
  switchOrder.value = ''
}

/* 阶段列表 */
const stageList = ref<any[]>([])
const stage = ref()

/* 主题列表 */
const topicId = ref()
const topicList = ref([] as any)

/* 是否过滤已选单词 */
const filterWord = ref(false)
watch(
  () => filterWord.value,
  () => {
    handleSeach()
  },
)

/* 单词列表 */
const selectedList = ref<SelectedListType[]>([]) // 选中的单词
const wordsList = ref<any[]>([]) // 只展示出来的部分单词列表
const vocabularyWordList = ref<Word[]>([]) // 选择词汇和主题后返回的全部单词，用于本地搜索
const filtrationList = ref<any[]>([]) // 已过滤的单词列表，过滤了已选择单词

function getWordList() {
  if (stage.value && topicId.value) {
    cascaderLoading.value = true
    getVocabularyWordList({
      vocabularyId: getVocabularyId(),
      topicId: topicId.value,
    })
      .then((list) => {
        /* 过滤接口中已选中的单词 */
        if (filterWord.value) {
          list = list.filter((item: any) =>
            item.meaningVoList.every((item: any) => !item.stageId),
          )
        }
        filtrationList.value = list

        /* 将数据改成 ElAutocomplete 能识别的格式 */
        vocabularyWordList.value = list.map((item: Word) => {
          return {
            value: item.spell,
            origin: item,
          }
        })
        wordsPagination.setData(list)
      })
      .finally(() => {
        cascaderLoading.value = false
      })
  }
}
function getVocabularyId() {
  const words = stageList.value.find((item) => item.name === stage.value)
  return words.id
}
// function getSelectedWordId() {
//   return selectedList.value.map((item) => {
//     return {
//       meaningId: Number((item.meaning as any).id),
//       wordId: Number(item.wordId),
//       spell: item.spell,
//     }
//   })
// }
/* Popover 选中单词 */
function handleWordSelected(word: SelectedListType) {
  const meaning = word.meaning as any
  selectedList.value.push({
    ...word,
    meaningId: meaning.id,
    meaning: meaning.znDesc,
  })

  /* 过滤放入到 selectedList 中的单词 */
  if (filterWord.value) {
    wordsList.value = wordsList.value.filter(
      (item) => item.wordId !== word.wordId,
    )
  }
}
/* 移除选中的单词 */
function closeTag(index: number, meaningId: string) {
  // deleteLevelWord(levelWordId).then(({ data: res }) => {
  selectedList.value.splice(index, 1)
  /* 清除下方单词列表中的selected状态 */
  wordsList.value.forEach((item) => {
    item.meaningVoList.forEach((meanItem: MeaningVo) => {
      if (meanItem.id === meaningId) {
        meanItem.selected = false
      }
    })
  })
  globalList.value.forEach((item) => {
    item.meaningVoList.forEach((meanItem: MeaningVo) => {
      if (meanItem.id === meaningId) {
        meanItem.selected = false
      }
    })
  })
  /* 重新过滤已选单词 */
  if (filterWord.value) {
    const list = filtrationList.value
    wordsList.value = list.filter((item) =>
      selectedList.value.every(
        (selectedItem) => selectedItem.wordId !== item.wordId,
      ),
    )
  }
  // }
  // });
}

/* 自动补全搜索框 */
const {
  state,
  querySearch,
  handleSelect: autoCompleteClick,
} = useAutocomplete(vocabularyWordList)
const cascaderLoading = ref(false)

function handleSeach() {
  if (state.value === '') {
    getWordList()
  } else {
    /* 匹配搜索关键字 */
    const result = vocabularyWordList.value.filter(
      (item: any) =>
        item.origin.spell.toLowerCase().indexOf(state.value.toLowerCase()) ===
        0,
    )
    const list = result.map((item: any) => item.origin)
    wordsPagination.setData(list)
  }
}

/* 加载单词列表 */
const wordsPagination = useInfiniteScroll(wordsList)

/* 全局搜索 */
const globalSeachStr = ref<string>('')
const globalList = ref<any[]>([])
const globalSeachPag = useInfiniteScroll(globalList, 80)
const globalLoading = ref(false)

function handleGlobalSeach() {
  if (!globalSeachStr.value) return
  globalLoading.value = true
  getVocabularyWordListByPrefix({
    // vocabularyId: getVocabularyId(),
    wordPrefix: globalSeachStr.value,
  })
    .then((res) => {
      globalSeachPag.setData(res)
    })
    .finally(() => {
      globalLoading.value = false
    })
}

/* Tab 组件 */
const activeTab = ref('theme')

/* 交换或插入关卡排序 */
const switchOrder = ref('')
// function toSwitch() {
//   if (!switchOrder.value) return
//   exchangeLevel({
//     levelNumToExchange: switchOrder.value,
//     levelId: props.diaData.id,
//   }).then(() => {
//     show.value = false
//     switchOrder.value = ''
//     emits('onRefresh')
//   })
// }
// function toInsertion() {
//   if (!switchOrder.value) return
//   insertLevel({
//     levelNumInFrontOf: switchOrder.value,
//     levelId: props.diaData.id,
//   }).then(() => {
//     show.value = false
//     switchOrder.value = ''
//     emits('onRefresh')
//   })
// }

onMounted(async () => {
  /* 获取阶段列表 */
  await getWordClassList().then((res) => {
    const data: any[] = res.rows
    stageList.value = data
    stage.value = stageList.value[0].name
  })
  /* 获取主题列表 */
  await getTopiclList().then((res) => {
    const data = res
    topicList.value = data
    topicId.value = topicList.value[0].id
    getWordList()
  })
})
</script>

<template>
  <el-dialog
    v-model="show"
    width="60vw"
    :title="Object.keys(diaData).length > 0 ? '编辑' : '新增'"
    align-center
    class="box"
    destroy-on-close
    @open="onOpen"
  >
    <div>
      <div class="edit__item">
        <div class="w-[96px] font-bold leading-[32px]">已选择单词：</div>
        <div class="words__list w-full">
          <span
            v-for="(item, index) in selectedList"
            :key="item.meaningId"
            class="words__item"
          >
            <el-popover width="auto">
              <template #reference>
                <el-tag
                  class="mx-1"
                  size="large"
                  closable
                  @close="closeTag(index, item.meaningId)"
                >
                  {{ item.spell }}</el-tag
                >
              </template>
              <div>{{ item.meaning }}</div>
            </el-popover>
          </span>
        </div>
      </div>
      <el-tabs v-model="activeTab" class="demo-tabs" stretch>
        <el-tab-pane label="主题筛选" name="theme">
          <div class="edit__item">
            <div class="edit-item-title">阶段</div>
            <div class="edit-item-content">
              <el-radio-group v-model="stage" size="large">
                <el-radio-button
                  v-for="item in stageList"
                  :key="item.id"
                  :label="item.name"
                  @change="getWordList"
                />
              </el-radio-group>
            </div>
          </div>
          <div class="edit__item">
            <div class="edit-item-title">主题</div>
            <div class="edit-item-content">
              <el-cascader-panel
                v-model="topicId"
                :options="topicList"
                :props="{
                  value: 'id',
                  label: 'nameZn',
                  children: 'childTopicList',
                  emitPath: false,
                  checkStrictly: true,
                }"
                @change="getWordList"
              />
            </div>
          </div>
          <div class="mt-[20px]">
            <div class="mb-4 flex items-center">
              <div class="w-[48px] leading-[32px]">搜索框</div>
              <div class="flex-1">
                <el-autocomplete
                  v-model="state"
                  :fetch-suggestions="querySearch"
                  clearable
                  class="inline-input w-50"
                  placeholder="请输入"
                  @select="autoCompleteClick"
                  @keyup.enter="handleSeach"
                />
                <el-button
                  type="primary"
                  class="ml-[12px]"
                  @click="handleSeach"
                >
                  查询
                </el-button>
                <el-checkbox
                  v-model="filterWord"
                  class="ml-[20px]"
                  label="过滤已选单词"
                  size="large"
                />
              </div>
            </div>
            <el-scrollbar v-loading="cascaderLoading" class="words__container">
              <div
                v-show="wordsList.length > 0"
                v-infinite-scroll="wordsPagination.load"
                :infinite-scroll-immediate="false"
              >
                <div class="words__list">
                  <Popover
                    v-for="item in wordsList"
                    :key="item.value"
                    v-bind="item"
                    :selected-list="selectedList"
                    :level-id="diaData.id"
                    @on-selected="handleWordSelected"
                  />
                </div>
              </div>
              <div v-show="wordsList.length === 0">
                <h4 class="text-center">暂无数据</h4>
              </div>
            </el-scrollbar>
          </div>
        </el-tab-pane>
        <el-tab-pane label="全局搜索" name="global" class="h-[400px]">
          <div class="mb-4 flex flex-row">
            <div class="w-[48px] leading-[32px]">搜索框</div>
            <div class="w-[200px]">
              <el-input
                v-model="globalSeachStr"
                @keyup.enter="handleGlobalSeach"
              />
            </div>
            <el-button
              type="primary"
              class="ml-[12px]"
              @click="handleGlobalSeach"
            >
              查询
            </el-button>
          </div>
          <div class="searcn__result__list">
            <el-scrollbar
              v-loading="globalLoading"
              class="words__container global__words"
            >
              <div
                v-show="globalList.length > 0"
                v-infinite-scroll="globalSeachPag.load"
                :infinite-scroll-immediate="false"
              >
                <div class="words__list">
                  <Popover
                    v-for="item in globalList"
                    :key="item.value"
                    v-bind="item"
                    :level-id="diaData.id"
                    :selected-list="selectedList"
                    :vocabulary-name="item.vocabularyName"
                    @on-selected="handleWordSelected"
                  />
                </div>
              </div>
              <div v-show="globalList.length === 0">
                <h4 class="text-center">暂无数据</h4>
              </div>
            </el-scrollbar>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="show = false">取消</el-button>
        <el-button type="primary" @click="handleSave"> 保存 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.edit__item {
  display: flex;

  & + .edit__item {
    margin-top: 20px;
  }

  .edit-item-title {
    width: 48px;
    font-weight: bold;
    line-height: 40px;
  }

  .edit-item-content {
    flex: 1;
  }
}

.words__container {
  height: 100px;
  padding: 20px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;

  .words__list {
    display: flex;
    flex-wrap: wrap;

    .words__item {
      padding: 6px 20px;
    }
  }

  &.global__words {
    height: 300px;
  }
}
</style>
