import { ActionSheet, Button, Image, Popup, Swipe, SwipeItem } from 'vant';
import {
  computed,
  defineComponent,
  nextTick,
  onMounted,
  onUnmounted,
  reactive,
  watch,
  ref
} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import styles from './index.module.less';
import iconButtonList from '../images/icon-button-list.png';
import MSticky from '@/components/m-sticky';
import ChoiceQuestion from '../model/choice-question';
import AnswerList from '../model/answer-list';
import DragQuestion from '../model/drag-question';
import KeepLookQuestion from '../model/keep-look-question';
import PlayQuestion from '../model/play-question';
import ErrorMode from '../model/error-mode';
import ResultFinish from '../model/result-finish';
import { eventUnit, QuestionType } from '../unit';
import request from '@/helpers/request';
import { useRect } from '@vant/use';
import MHeader from '@/components/m-header';
import { useEventListener, useInterval, useWindowScroll } from '@vueuse/core';

export default defineComponent({
  name: 'unit-detail',
  setup() {
    const route = useRoute();
    const router = useRouter();
    const swipeRef = ref();
    const state = reactive({
      background: 'transparent',
      color: '#fff',
      visiableError: false,
      visiableAnswer: false,
      id: route.query.id,
      currentIndex: 0,
      questionList: [] as any,
      page: 1,
      rows: 10,
      total: 0,
      isFinish: false, // 是否完成加载
      visiableInfo: {
        show: false,
        operationType: 'RESULT' as 'RESULT' | 'BACK' | 'CONTINUE' | 'GRASP',
        type: 'DEFAULT' as 'DEFAULT' | 'FAIL' | 'PASS' | 'GOOD' | 'COUNTDOWN',
        content: '',
        showCancelButton: false,
        confirmButtonText: '',
        cancelButtonText: '',
        title: '',
        graspItem: {} as any
      },
      nextStatus: false,
      swipeHeight: 'auto' as any,
      answerAnalysis: '',
      questionTypeCode: '',
      overResult: {
        time: '00:00', // 时长
        questionLength: 0, // 答题数
        errorLength: 0, // 错题数
        rate: 0 // 正确率
      }
    });

    // 计时
    const { counter, resume, pause } = useInterval(1000, { controls: true });

    const getExamDetails = async () => {
      try {
        const { data } = await request.post(
          '/edu-app/studentUnitExamination/errorEdition',
          {
            data: {
              page: state.page,
              rows: state.rows
            }
          }
        );
        const temp = data || {};
        state.total = temp.total || 0;
        state.isFinish = temp.current < temp.pages ? false : true;
        temp.records.forEach((item: any) => {
          item.showAnalysis = false; // 默认不显示解析
          item.grasp = false; // 是否掌握题目
          item.analysis = {
            message: item.answerAnalysis,
            topic: true, // 是否显示结果
            userResult: false // 用户答题对错
          };
          item.userAnswer = []; // 用户答题
        });
        state.questionList.push(...(temp.records || []));
      } catch {
        //
      }
    };

    // 监听索引
    watch(
      () => state.currentIndex,
      () => {
        console.log(state.currentIndex, 'index');
        // 判断是否在倒数第三题，并且没有加载完
        if (
          state.currentIndex + 3 >= state.questionList.length &&
          !state.isFinish
        ) {
          state.page = state.page + 1;
          getExamDetails();
        }
      }
    );

    /** 已掌握此题 */
    const onGraspQuestion = async (item: any) => {
      // 判断是否掌握此题
      if (item.grasp) return;
      state.visiableInfo.show = true;
      state.visiableInfo.title = '确定掌握此题？';
      state.visiableInfo.showCancelButton = true;
      state.visiableInfo.operationType = 'GRASP';
      state.visiableInfo.cancelButtonText = '取消';
      state.visiableInfo.confirmButtonText = '确定';
      state.visiableInfo.content = `你确定已掌握该题知识要点，此题将移除你的错题集。`;
      state.visiableInfo.graspItem = item;
    };

    /** 已掌握此题确认 */
    const onGraspQuestionConfirm = async () => {
      try {
        state.visiableInfo.show = false;
        await request.get('/edu-app/studentExaminationErrorEdition/del', {
          hideLoading: false,
          params: {
            studentExaminationErrorEditionId:
              state.visiableInfo.graspItem.studentExaminationErrorEditionId
          }
        });
        state.visiableInfo.graspItem.grasp = true;
      } catch {
        //
      }
    };

    /**
     * @description 下一题 | 测试完成
     */
    const onNextQuestion = async () => {
      try {
        const questionList = state.questionList || [];

        let result: any = {};
        questionList.forEach((question: any, index: number) => {
          // 格式化所有题目的答案
          if (index === state.currentIndex) {
            result = {
              questionId: question.id,
              details: question.userAnswer || []
            };
          }
        });

        const { data } = await request.post(
          '/edu-app/studentUnitExamination/submitTrainingAnswer',
          {
            hideLoading: true,
            data: result
          }
        );
        // 初始化是否显示解析
        questionList.forEach((question: any, index: number) => {
          // 格式化所有题目的答案
          if (index === state.currentIndex) {
            state.answerAnalysis = question.answerAnalysis;
            state.questionTypeCode = question.questionTypeCode;
            question.showAnalysis = true;
            question.analysis.userResult = data;
          }
        });

        // 判断是否是最后一题
        if (state.questionList.length === state.currentIndex + 1) {
          eventUnit.emit('unitAudioStop');
          state.visiableInfo.show = true;
          state.visiableInfo.title = '练习完成';
          state.visiableInfo.showCancelButton = true;
          state.visiableInfo.operationType = 'CONTINUE';
          state.visiableInfo.cancelButtonText = '再等等';
          state.visiableInfo.confirmButtonText = '确认完成';
          state.visiableInfo.content = `确认本次练习的题目都完成了吗？`;

          return;
        }

        if (data) {
          swipeRef.value?.next();
        } else {
          state.visiableError = true;
        }
      } catch {
        //
      }
    };

    //
    const getAnswerResult = computed(() => {
      const questionList = state.questionList || [];
      let count = 0;
      let passCount = 0;
      let noPassCount = 0;
      questionList.forEach((item: any) => {
        if (item.showAnalysis) {
          count += 1;
          if (item.analysis.userResult) {
            passCount += 1;
          } else {
            noPassCount += 1;
          }
        }
      });

      return {
        count,
        passCount,
        noPassCount
      };
    });

    /**
     * @description 重置当前的题目高度
     * @param {any} scroll 是否滚动到顶部
     */
    let size = 0;
    const resizeSwipeItemHeight = (scroll = true) => {
      nextTick(() => {
        scroll && window.scrollTo(0, 0);
        setTimeout(() => {
          const currentItemDom: any = document
            .querySelectorAll('.van-swipe-item')
            [state.currentIndex]?.querySelector('.swipe-item-question');

          const allImg = currentItemDom?.querySelectorAll(
            '.answerTitleImg img'
          );
          let status = true;
          // console.log(allImg)
          allImg?.forEach((img: any) => {
            if (!img.complete) {
              status = false;
            }
          });
          // 判断图片是否加载完了
          if (!status && size < 3) {
            setTimeout(() => {
              size += 1;
              resizeSwipeItemHeight(scroll);
            }, 300);
          }
          if (status) {
            size = 0;
          }
          const rect = useRect(currentItemDom);
          state.swipeHeight = rect.height;
        }, 100);
      });
    };

    const onConfirmResult = () => {
      if (state.visiableInfo.operationType === 'RESULT') {
        state.visiableInfo.show = false;
        onAfter();
      } else if (state.visiableInfo.operationType === 'BACK') {
        state.visiableInfo.show = false;
        onAfter();
      } else if (state.visiableInfo.operationType === 'CONTINUE') {
        onResultPopup();
      } else if (state.visiableInfo.operationType === 'GRASP') {
        onGraspQuestionConfirm();
      }
    };
    const onCloseResult = async () => {
      const operationType = state.visiableInfo.operationType;
      if (operationType === 'RESULT') {
      } else if (operationType === 'BACK') {
        state.visiableInfo.show = false;
        window.history.pushState(null, '', document.URL);
        window.addEventListener('popstate', onBack, false);
      } else if (operationType === 'CONTINUE' || operationType === 'GRASP') {
        state.visiableInfo.show = false;
      }
    };

    /** 结果页面弹窗 */
    const onResultPopup = () => {
      const answerResult = getAnswerResult.value;
      let rate = 0;

      if (answerResult.count > 0) {
        rate = Math.floor((answerResult.passCount / answerResult.count) * 100);
      }

      const times = counter.value;
      const minute =
        Math.floor(times / 60) >= 10
          ? Math.floor(times / 60)
          : '0' + Math.floor(times / 60);
      const seconds = times % 60 >= 10 ? times % 60 : '0' + (times % 60);
      state.overResult = {
        time: minute + ':' + seconds, // 时长
        questionLength: answerResult.count, // 答题数
        errorLength: answerResult.noPassCount, // 错题数
        rate // 正确率
      };
      // 重置计时
      pause();
      counter.value = 0;

      // 60 及格
      // 85 及以上优秀
      state.visiableInfo.show = true;
      state.visiableInfo.title = '已完成';
      state.visiableInfo.showCancelButton = false;
      state.visiableInfo.operationType = 'RESULT';
      state.visiableInfo.confirmButtonText = '确认';
      state.visiableInfo.content = `<div>您已完成本次测试，答对<span class='${
        styles.right
      }'>${answerResult.passCount}</span>，答错<span class='${styles.error}'>${
        answerResult.count - answerResult.passCount
      }</span>，正确率${rate}%~</div>`;
    };

    // 拦截
    const onBack = () => {
      const answerResult = getAnswerResult.value;
      state.visiableInfo.show = true;
      state.visiableInfo.title = '确认退出吗？';
      state.visiableInfo.showCancelButton = true;
      state.visiableInfo.operationType = 'BACK';
      state.visiableInfo.cancelButtonText = '取消';
      state.visiableInfo.confirmButtonText = '确定';
      state.visiableInfo.content = `您已经完成${
        answerResult.passCount + answerResult.noPassCount
      }道题了，继续做题可以巩固所学知识哦～`;
      eventUnit.emit('unitAudioStop');
    };

    const onAfter = () => {
      window.removeEventListener('popstate', onBack, false);
      router.back();
    };

    onMounted(async () => {
      useEventListener(document, 'scroll', () => {
        const { y } = useWindowScroll();
        if (y.value > 52) {
          state.background = '#fff';
          state.color = '#323333';
        } else {
          state.background = 'transparent';
          state.color = '#fff';
        }
      });
      await getExamDetails();

      resizeSwipeItemHeight();

      window.history.pushState(null, '', document.URL);
      window.addEventListener('popstate', onBack, false);
    });

    onUnmounted(() => {
      // 关闭所有音频
      eventUnit.emit('unitAudioStop');
    });
    return () => (
      <div class={styles.unitDetail}>
        <MSticky position="top">
          <MHeader
            border={false}
            background={state.background}
            color={state.color}
          />
        </MSticky>
        <Swipe
          loop={false}
          showIndicators={false}
          ref={swipeRef}
          duration={300}
          touchable={false}
          class={styles.unitSwipe}
          style={{ paddingBottom: '12px' }}
          lazyRender
          height={state.swipeHeight}
          onChange={(index: number) => {
            eventUnit.emit('unitAudioStop');
            state.currentIndex = index;
            resizeSwipeItemHeight();
          }}>
          {state.questionList.map((item: any, index: number) => (
            <SwipeItem>
              <div class="swipe-item-question">
                {item.questionTypeCode === QuestionType.RADIO && (
                  <ChoiceQuestion
                    v-model:value={item.userAnswer}
                    index={index + 1}
                    data={item}
                    type="radio"
                    showAnalysis={item.showAnalysis}
                    analysis={item.analysis}>
                    {{
                      title: () => (
                        <div class={styles.questionTitle}>
                          <div class={styles.questionNum}>
                            <p class={styles.pointName}>
                              {item.knowledgePointName}
                            </p>
                            <span>{state.currentIndex + 1}</span>/{state.total}
                          </div>
                          <Button
                            round
                            plain
                            size="mini"
                            color={item.grasp ? '#FF5A56' : '#1CACF1'}
                            class={styles.controlBtn}
                            disabled={item.grasp}
                            onClick={() => onGraspQuestion(item)}>
                            {item.grasp ? '已掌握此题' : '掌握此题'}
                          </Button>
                        </div>
                      )
                    }}
                  </ChoiceQuestion>
                )}
                {item.questionTypeCode === QuestionType.CHECKBOX && (
                  <ChoiceQuestion
                    v-model:value={item.userAnswer}
                    index={index + 1}
                    data={item}
                    type="checkbox"
                    showAnalysis={item.showAnalysis}
                    analysis={item.analysis}>
                    {{
                      title: () => (
                        <div class={styles.questionTitle}>
                          <div class={styles.questionNum}>
                            <p class={styles.pointName}>
                              {item.knowledgePointName}
                            </p>
                            <span>{state.currentIndex + 1}</span>/{state.total}
                          </div>

                          <Button
                            round
                            plain
                            size="mini"
                            color={item.grasp ? '#FF5A56' : '#1CACF1'}
                            class={styles.controlBtn}
                            disabled={item.grasp}
                            onClick={() => onGraspQuestion(item)}>
                            {item.grasp ? '已掌握此题' : '掌握此题'}
                          </Button>
                        </div>
                      )
                    }}
                  </ChoiceQuestion>
                )}
                {item.questionTypeCode === QuestionType.SORT && (
                  <DragQuestion
                    v-model:value={item.userAnswer}
                    onUpdate:value={() => {
                      // 如果是空则滑动到顶部
                      const status =
                        item.userAnswer && item.userAnswer.length > 0
                          ? false
                          : true;
                      resizeSwipeItemHeight(status);
                    }}
                    data={item}
                    index={index + 1}
                    showAnalysis={item.showAnalysis}
                    analysis={item.analysis}>
                    {{
                      title: () => (
                        <div class={styles.questionTitle}>
                          <div class={styles.questionNum}>
                            <p class={styles.pointName}>
                              {item.knowledgePointName}
                            </p>
                            <span>{state.currentIndex + 1}</span>/{state.total}
                          </div>
                          <Button
                            round
                            plain
                            size="mini"
                            color={item.grasp ? '#FF5A56' : '#1CACF1'}
                            class={styles.controlBtn}
                            disabled={item.grasp}
                            onClick={() => onGraspQuestion(item)}>
                            {item.grasp ? '已掌握此题' : '掌握此题'}
                          </Button>
                        </div>
                      )
                    }}
                  </DragQuestion>
                )}
                {item.questionTypeCode === QuestionType.LINK && (
                  <KeepLookQuestion
                    v-model:value={item.userAnswer}
                    data={item}
                    index={index + 1}
                    showAnalysis={item.showAnalysis}
                    analysis={item.analysis}>
                    {{
                      title: () => (
                        <div class={styles.questionTitle}>
                          <div class={styles.questionNum}>
                            <p class={styles.pointName}>
                              {item.knowledgePointName}
                            </p>
                            <span>{state.currentIndex + 1}</span>/{state.total}
                          </div>
                          <Button
                            round
                            plain
                            size="mini"
                            color={item.grasp ? '#FF5A56' : '#1CACF1'}
                            class={styles.controlBtn}
                            disabled={item.grasp}
                            onClick={() => onGraspQuestion(item)}>
                            {item.grasp ? '已掌握此题' : '掌握此题'}
                          </Button>
                        </div>
                      )
                    }}
                  </KeepLookQuestion>
                )}
                {item.questionTypeCode === QuestionType.PLAY && (
                  <PlayQuestion
                    v-model:value={item.userAnswer}
                    data={item}
                    index={index + 1}
                    unitId={state.id as any}
                    showAnalysis={item.showAnalysis}
                    analysis={item.analysis}>
                    {{
                      title: () => (
                        <div class={styles.questionTitle}>
                          <div class={styles.questionNum}>
                            <span>{state.currentIndex + 1}</span>/{state.total}
                          </div>
                          {/* <div class={styles.questionType}>
                            <i></i>
                            <span>{item.knowledgePointName}</span>
                          </div> */}
                          <Button
                            round
                            plain
                            size="mini"
                            color={item.grasp ? '#FF5A56' : '#1CACF1'}
                            disabled={item.grasp}
                            class={styles.controlBtn}
                            onClick={() => onGraspQuestion(item)}>
                            {item.grasp ? '已掌握此题' : '掌握此题'}
                          </Button>
                        </div>
                      )
                    }}
                  </PlayQuestion>
                )}
              </div>
            </SwipeItem>
          ))}
        </Swipe>

        <MSticky position="bottom">
          <div class={['btnGroup btnMore', styles.btnSection]}>
            <Button
              round
              block
              class={
                state.currentIndex > 0 ? styles.activePrevBtn : styles.prevBtn
              }
              disabled={state.currentIndex > 0 ? false : true}
              onClick={() => {
                swipeRef.value?.prev();
              }}>
              上一题
            </Button>
            <Button
              block
              round
              class={styles.nextBtn}
              onClick={onNextQuestion}
              loading={state.nextStatus}
              disabled={state.nextStatus}>
              {state.questionList.length === state.currentIndex + 1
                ? '提交'
                : '下一题'}
            </Button>
            <Image
              src={iconButtonList}
              class={[styles.wapList, 'van-haptics-feedback']}
              onClick={() => (state.visiableAnswer = true)}
            />
          </div>
        </MSticky>

        {/* 题目集合 */}
        <ActionSheet
          v-model:show={state.visiableAnswer}
          title="题目列表"
          safeAreaInsetBottom>
          <AnswerList
            value={state.questionList}
            lookType={'PRACTICE'}
            statusList={[
              {
                text: '答对',
                color: '#1CACF1'
              },
              {
                text: '答错',
                color: '#FF8486'
              },
              {
                text: '未答',
                color: '#EAEAEA'
              }
            ]}
            onSelect={(item: any) => {
              // 跳转，并且跳过动画
              swipeRef.value?.swipeTo(item, {
                immediate: true
              });
              state.visiableAnswer = false;
            }}
          />
        </ActionSheet>

        <Popup
          v-model:show={state.visiableError}
          style={{ width: '90%' }}
          round
          closeOnClickOverlay={false}>
          <ErrorMode
            onClose={() => (state.visiableError = false)}
            answerAnalysis={state.answerAnalysis}
            questionTypeCode={state.questionTypeCode}
            onConform={() => {
              swipeRef.value?.next();
              state.answerAnalysis = '';
            }}
          />
        </Popup>

        <Popup
          v-model:show={state.visiableInfo.show}
          closeOnClickOverlay={false}
          style={{
            background: 'transparent',
            width: '100%',
            maxWidth: '100%',
            transform: 'translateY(-55%)'
          }}>
          <ResultFinish
            title={state.visiableInfo.title}
            showCancelButton={state.visiableInfo.showCancelButton}
            cancelButtonText={state.visiableInfo.cancelButtonText}
            confirmButtonText={state.visiableInfo.confirmButtonText}
            status={state.visiableInfo.type}
            content={state.visiableInfo.content}
            contentHtml
            onConform={onConfirmResult}
            onClose={onCloseResult}
          />
        </Popup>
      </div>
    );
  }
});
