import type { Level, Character } from '../interface'
import { useHardModeStore } from '@/stores/learnWord/useLearnWordStore.ts'
import { XMessage } from '@/hooks'

// import useSoundEffect from '@/hooks/useSoundEffect';
import useAudio from './useAudio.ts'
import { question_right, question_wrong } from '../../index.ts'
import { useRoute } from 'vue-router'
import learnWordApi from '@/api/subject/learnWord.ts'
import wordTestApi from '@/api/subject/wordTest.ts'
let propsNum: anyObj
nextTick(() => {
  propsNum = useHardModeStore()
})

// const sound = useSoundEffect();
export const showNext = ref(false)
const onClickNextFlag = ref(1)
export const totalData = ref<anyObj[]>([])
export const WordTest = ref(false)
export const onNetLoading = ref(false) // 是否正在加载保存结果

/* 洗牌算法 */
function shuffle(arr: Character[]) {
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
    const t = arr[i]
    arr[i] = arr[j]
    arr[j] = t
  }
}

export function useAnswer(handleRight: () => void, handle: anyObj, isWordTest?: boolean) {
  const charList = computed(() => {
    return answer.data.currentData.charList
  })

  const sound = useAudio()

  onMounted(() => {
    if (!useRoute().path.includes('wordTest')) {
      window.addEventListener('keydown', inputList.keyBoardInput)
    }
  })

  onUnmounted(() => {
    window.removeEventListener('keydown', inputList.keyBoardInput)
  })

  // 退出时候更改showNext
  const handleChangeNext = () => {
    showNext.value = false
  }
  // 记录单词测试数据
  function saveWordTestApi(istrue = false, isError = false) {
    onNetLoading.value = true
    wordTestApi
      .saveWordTest({
        duration: new Date().getTime() - answer.data.startTime,
        questionType: 1,
        levelId: answer.data.currentData.levelId,
        saveTime: new Date().getTime(),
        sessionId: answer.data.currentData.sessionId,
        surrender: istrue ? 0 : 1,
        testResult: istrue ? (isError ? 0 : 1) : 0,
        wordId: answer.data.currentData.wordId,
        imageUrl: answer.data.currentData.titlePicture,
        meaningId: answer.data.currentData.meaningId,
        titleFrom: answer.data.currentData.titleFrom,
        levelType: answer.data.currentData.levelType,
      })
      .then(res => {
        if (!(res?.data.code === 200)) {
          wordTestApi
            .saveWordTest({
              duration: new Date().getTime() - answer.data.startTime,
              questionType: 1,
              saveTime: new Date().getTime(),
              levelId: answer.data.currentData.levelId,
              sessionId: answer.data.currentData.sessionId,
              surrender: istrue ? 0 : 1,
              testResult: istrue ? (isError ? 0 : 1) : 0,
              wordId: answer.data.currentData.wordId,
              imageUrl: answer.data.currentData.titlePicture,
              meaningId: answer.data.currentData.meaningId,
              titleFrom: answer.data.currentData.titleFrom,
              levelType: answer.data.currentData.levelType,
            })
            .finally(() => {
              onNetLoading.value = false
            })
        } else {
          onNetLoading.value = false
        }
      })
  }

  // 添加正确字母的索引
  function _addRightIndex(itemMap: any, indexMap: any, exclude: (item: Character) => boolean) {
    for (let i = 0; i < charList.value.length; i++) {
      const item = charList.value[i]
      // 不符合条件的，直接跳过
      if (exclude(item)) continue
      // 索引数组
      const itemList = itemMap[item.value]
      const listLen = itemList?.length || 0
      if (!listLen) {
        // 还没有加过
        itemMap[item.value] = [i]
        indexMap[i] = 1
      } else if (listLen < item.maxChoose) {
        itemList.push(i)
        indexMap[i] = 1
      }
    }
  }

  /* 道具 */
  const gameProps = {
    init() {
      this.glass.used.value = 0
      this.bomb.used.value = 0
    },
    glass: {
      used: ref(0),
      useEffect: function () {
        if (propsNum.glassNum <= 0) return
        answer.data.useTools = 1
        learnWordApi.postUseItems({ type: 2 }).then((res: any) => {
          const emptyCell = inputList.data.length - inputList.data.count

          if (emptyCell <= 2) {
            return XMessage.error('空格数少于2，无法使用')
          }
          // 先清除
          inputList.clear()

          const eliminateNum = Math.floor(1 + (emptyCell - 2) * Math.random()) // 随机获取要消除的个数
          for (let i = 0; i < eliminateNum; i++) {
            const emptyPosition = [] // 获取当前的空格子
            for (let j = 0; j < inputList.data.length; j++) {
              if (!inputList.data.queen[j]) {
                emptyPosition.push(j)
              }
            }

            const random = Math.floor(emptyPosition.length * Math.random())
            const position = emptyPosition[random] // 随机抽取一个位置
            const character = answer.data.currentData.spell[position] // 随机到要显现的字母

            /* 将随机到的字母加入到选项框里 */
            let canSelect = true
            charList.value.forEach(item => {
              if (item.value === character && !item.selected && canSelect) {
                inputList.data.queen[position] = item
                item.selected = true
                item.fixed = true
                canSelect = false
                inputList.data.count++
                if (position === inputList.data.index) {
                  inputList.indexAutoIncrement()
                }
              }
            })
            sound.play('fill_in.mp3')
          }
          propsNum.glassNum--
          gameProps.glass.used.value++
        })
      },
    },
    bomb: {
      used: ref(0),
      useEffect: function (animateFun: () => void) {
        if (propsNum.bombNum <= 0) return
        answer.data.useTools = 1
        learnWordApi.postUseItems({ type: 1 }).then(async (res: any) => {
          // 所有需要保留的索引
          // item.value为key，索引数组为value
          const keepIndexValueMap = {} as any
          // 索引为key，1为value
          const keepIndexMap = [] as number[]
          // 遍历所有的字母,先找出放大镜的字母索引
          // 没有被放大镜选中的字母，直接跳过
          _addRightIndex(keepIndexValueMap, keepIndexMap, item => !item.fixed)

          // 遍历所有的字母,找出除放大镜以外的，其他正确字母的索引
          // 被放大镜选中的字母，直接跳过
          // 被答案字母，直接跳过
          _addRightIndex(keepIndexValueMap, keepIndexMap, item => item.fixed || !item.choose)

          // 拿到需要删除的索引
          const delIndexList: Array<number> = [] // 存储错误选项的索引，用于随机清除
          for (let i = 0; i < charList.value.length; i++) {
            const item = charList.value[i]
            // 已经被删除了
            if (item.prop) continue
            if (keepIndexMap[i]) continue
            delIndexList.push(i)
          }

          if (delIndexList.length === 0) {
            return XMessage.error('已经无法再删除')
          }

          animateFun?.()

          setTimeout(() => {
            // 先清除
            inputList.clear()

            for (const position of delIndexList) {
              const character = charList.value[position] // 随机到要显现的字母

              /* 将随机到的字母隐藏 */
              character.selected = true
              character.prop = true // 标记为道具消除
            }
          }, 1300)

          propsNum.bombNum--
          gameProps.bomb.used.value++
        })
      },
    },
    flag: {
      useEffect: function () {
        answer.showAnswer()
        answer.data.result = question_right
        answer.data.prop = true // 标记使用了投降道具
        answer.data.useTools = 1
        sound.play('fill_in.mp3')

        if (answer.data.currentData.accent) {
          handle.playAccent()
        }

        // OpenPop();
        inputList.data.enable = false
        answer.data.currentData.usedTime = Math.round(
          (new Date().getTime() - answer.data.startTime) / 1000,
        )
        propsNum.usedTime += answer.data.currentData.usedTime
        // 新增
        showNext.value = true
        // 每调用一次postWordRecord接口后就清空道具使用
        gameProps.init()
        // setTimeout(() => {
        //   sound.play('show_nextBtn.mp3')
        // }, 1800)
        if (WordTest.value) {
          saveWordTestApi()
          return
        }
        const postData = {
          bomb: gameProps.bomb.used.value,
          glass: gameProps.glass.used.value,
          surrender: 1,
          levelId: propsNum.urlQuery.nextLevelId
            ? propsNum.urlQuery.nextLevelId
            : propsNum.urlQuery.levelId
              ? propsNum.urlQuery.levelId
              : answer.data.currentData.levelId,
          levelType: 2,
          result: 0,
          costTime: answer.data.currentData.usedTime,
          sessionId: answer.data.currentData.sessionId,
          wordId: answer.data.currentData.wordId,
          meaningId: answer.data.currentData.meaningId,
          useTools: answer.data.useTools,
          titleFrom: answer.data.currentData.titleFrom,
        }
        totalData.value.push(postData)

        learnWordApi
          .postWordRecord(postData)
          .then(async (res: any) => {})
          .catch(() => {
            learnWordApi.postWordRecord(postData)
          })
      },
    },
  }

  const inputList = {
    data: reactive({
      length: 0,
      index: 0,
      enable: true, // 输入状态
      queen: [] as any, // 已输入队列
      queenCopy: [] as any, // 已输入队列复制
      count: 0, // 已输入个数
    }),
    init() {
      this.data.length = answer.data.currentData?.spell?.split('').length
      this.reset()
    },
    reset() {
      this.data.queen = []
      this.data.index = 0
      this.data.enable = true
      this.data.count = 0
    },
    choose(charItem: Character, playSound = true) {
      if (isWordTest ? !charItem.count : charItem.selected) return // 已选不能再选
      if (!this.data.enable) return
      if (this.data.count >= this.data.length) return // 输入框已满不能再输入
      this.data.queen[this.data.index] = isWordTest ? { ...charItem } : charItem
      this.data.queenCopy[this.data.index] = charItem

      isWordTest ? charItem.count-- : (charItem.selected = true)
      this.data.count++
      // if (playSound) {
      //   sound.play('fill_in.mp3')
      // }
      // 索引自增
      this.indexAutoIncrement()
      // 如果填写完则自动答题
      if (this.data.count === this.data.length) {
        // 进入判断
        answer.answering()
      }
    },

    keyBoardInput(e: any) {
      const _this = inputList.data

      if (e.key === 'Backspace') {
        if (answer.data.result === question_right) return
        inputList.backspace()
      }
      if (_this.enable) {
        let canSelect = true
        if (!charList.value) return
        if (isWordTest) {
          return
        }
        charList.value.forEach(item => {
          if (item.value === e.key && canSelect && !item.selected) {
            canSelect = false
            inputList.choose(item, false)
            sound.play('keyBoard.mp3')
          }
        })
      }
    },

    indexAutoIncrement() {
      this.data.index++
      if (this.data.index >= this.data.length) {
        this.data.enable = false
      } else if (this.data.queen[this.data.index]?.value) {
        // 如果自增后的数组索引处已经有值，则继续自增
        this.indexAutoIncrement()
      }
    },
    // 清除
    clear() {
      while (this.data.queen.filter((i: any) => i && !i.fixed).length) {
        this.backspace()
      }
    },
    // 退一格
    backspace() {
      if (!this.data.count) return
      /* 如果答错则恢复状态重新答题 */
      if (answer.data.result === question_wrong) {
        answer.data.result = ''
      }
      /* 先恢复字母选项的显示再进行删除 */
      for (let index = this.data.queen.length - 1; index >= 0; index--) {
        const item = isWordTest ? this.data.queenCopy[index] : this.data.queen[index]
        if (item && (isWordTest || !item.fixed)) {
          isWordTest ? item.count++ : (item.selected = false)
          this.data.queen[index] = undefined
          this.data.queenCopy[index] = undefined

          // this.data.queen.splice(index, 1)
          // this.data.queenCopy.splice(index, 1)
          if (this.data.index > index) {
            this.data.index = index
          }
          this.data.count--
          break
        }
      }
      this.data.enable = true
    },
  }

  const answer = {
    data: reactive({
      index: 0,
      length: 0,
      result: null as string | null, // 答题结果
      currentData: {} as Level,
      numberOfAnswers: 0,
      prop: false, // 标记使用了投降道具（动效针对字母消失）
      useTools: 0, // 代表在本个单词答题中有没有使用过任一道具
      hasErrorInThisWord: false,
      apiResult: null,
      startTime: 0,
    }),
    load(data: Level) {
      if (data.charList) {
        shuffle(data.charList) // 将词组选项洗牌
      }
      answer.data.currentData = data
      this.reset()
      inputList.init()
      gameProps.init()
      showNext.value = false
    },
    reset() {
      const _this = answer.data
      _this.result = null
      _this.numberOfAnswers = 0
      _this.startTime = new Date().getTime()
      _this.prop = false // 清空投降道具标记
      _this.useTools = 0
      _this.hasErrorInThisWord = false
    },
    async answering(surrender = 0) {
      try {
        const _this = answer.data
        const choose = inputList.data.queen.map((item: any) => item?.value).join('')
        _this.numberOfAnswers++
        _this.currentData.usedTime = Math.round((new Date().getTime() - _this.startTime) / 1000)

        /* propsNum.usedTime 是所有题目的总时长，每次答完题后需要累加 */
        propsNum.usedTime += _this.currentData.usedTime

        if (choose === _this.currentData.spell) {
          _this.result = question_right
          inputList.data.enable = false

          // nextTick(() => {
          //   sound.play('right.mp3')
          // })

          // 使用道具或者做错过则显示下一题按钮和标生按钮，否则直接进入下一题
          if (answer.data.useTools) {
            // if (answer.data.useTools || answer.data.hasErrorInThisWord) {
            showNext.value = true
          }

          if (showNext.value && answer.data.currentData.accent) {
            handle.playAccent()
          }
          setTimeout(() => {
            if (!showNext.value) {
              handleRight()
            } else {
              // setTimeout(() => {
              //   sound.play('show_nextBtn.mp3')
              // }, 300)
            }
          }, 100)

          answer
            .updateWordStatus(true)
            .then(async () => {
              //
            })
            .catch(() => {
              // uni.showToast({
              //     title: '网络异常，请重新作答',
              //     icon: 'none',
              // });
              // inputList.clear();
              // answer.reset();
            })
        } else {
          _this.result = question_wrong
          answer.data.hasErrorInThisWord = true

          // 错误动效
          const $box = document.getElementById('hardModeBox')
          const $inputBox = $box?.getElementsByClassName('input__list')[0]
          $inputBox?.classList.add('animate__animated', 'animate__shakeX')
          $inputBox?.addEventListener('animationend', e => {
            $inputBox?.classList.remove('animate__shakeX')
          })

          nextTick(() => {
            sound.play('error.mp3')
          })
          _this.startTime = new Date().getTime()
          // 每调用一次postWordRecord接口后就清空道具使用
          gameProps.init()
          if (WordTest.value) {
            saveWordTestApi(true, true)
            return
          }
          const postData = {
            bomb: gameProps.bomb.used.value,
            glass: gameProps.glass.used.value,
            surrender: surrender,
            levelId: propsNum.urlQuery.nextLevelId
              ? propsNum.urlQuery.nextLevelId
              : propsNum.urlQuery.levelId
                ? propsNum.urlQuery.levelId
                : answer.data.currentData.levelId,
            levelType: 2,
            result: 0,
            costTime: answer.data.currentData.usedTime,
            sessionId: answer.data.currentData.sessionId,
            wordId: answer.data.currentData.wordId,
            meaningId: answer.data.currentData.meaningId,
            useTools: answer.data.useTools,
            titleFrom: answer.data.currentData.titleFrom,
          }

          totalData.value.push(postData)

          learnWordApi
            .postWordRecord(postData)
            .then((res: any) => {})
            .catch(() => {
              learnWordApi.postWordRecord(postData)
            })
        }
      } catch (err) {
        console.log(err)
      }
    },
    // 点击下一题
    async nextWords() {
      showNext.value = false
      if (answer.data.apiResult) {
        // propsNum.bombNum = answer.data.apiResult.bomb;
        // propsNum.glassNum = answer.data.apiResult.glass;
        // propsNum.score = answer.data.apiResult.hardScore;
      }
      const dom = document.querySelector('.page__content__right')
      if (dom) {
        dom.scrollTop = 0
      }
    },
    // 调用接口更新当前单词状态
    async updateWordStatus(isNextWords = false) {
      if (WordTest.value) {
        saveWordTestApi(true)
        return
      }

      // if (!answer.data.hasErrorInThisWord) {
      propsNum.score += 25
      // }
      // if (isNextWords) {
      //     propsNum.score = res.data.hardScore;
      // } else {
      //     answer.data.apiResult = res.data;
      // }
      const postData = {
        bomb: gameProps.bomb.used.value,
        glass: gameProps.glass.used.value,
        surrender: 0,
        levelId: propsNum.urlQuery.nextLevelId
          ? propsNum.urlQuery.nextLevelId
          : propsNum.urlQuery.levelId
            ? propsNum.urlQuery.levelId
            : answer.data.currentData.levelId,
        levelType: 2,
        result: 1,
        costTime: answer.data.currentData.usedTime,
        sessionId: answer.data.currentData.sessionId,
        wordId: answer.data.currentData.wordId,
        meaningId: answer.data.currentData.meaningId,
        useTools: answer.data.useTools,
        titleFrom: answer.data.currentData.titleFrom,
      }
      totalData.value.push(postData)
      return new Promise((resolve, reject) => {
        learnWordApi
          .postWordRecord(postData)
          .then(res => {})
          .catch(() => {
            learnWordApi.postWordRecord(postData)
          })
      })
    },
    showAnswer() {
      /* 显示正确答案 */
      const answer = this.data.currentData.spell
      const answerArr: Array<Character> = []
      for (const item of answer) {
        let canSelect = true
        this.data.currentData.charList.forEach(character => {
          if (character.value === item && canSelect) {
            answerArr.push(character)
            canSelect = false
          }
        })
      }

      inputList.data.queen = answerArr
    },
  }

  watch(onClickNextFlag, (newVal, oldVal) => {
    if (newVal !== oldVal) {
      answer.nextWords()
    }
  })

  return {
    gameProps,
    inputList,
    answer,
    showNext,
    totalData,
    onClickNextFlag,
    handleChangeNext,
  }
}
export function clear() {
  totalData.value = []
}
