import { ActionSheet, Button, Image, Popup, Swipe, SwipeItem } from 'vant';
import {
  defineComponent,
  nextTick,
  onMounted,
  onUnmounted,
  reactive,
  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 ResultFinish from '../model/result-finish';
import { eventUnit, QuestionType } from '../unit';
import request from '@/helpers/request';
import { CurrentTime, useCountDown, useRect } from '@vant/use';
import MHeader from '@/components/m-header';
import { useEventListener, useWindowScroll } from '@vueuse/core';

export default defineComponent({
  name: 'unit-detail',
  setup() {
    const route = useRoute();
    const router = useRouter();
    const swipeRef = ref();
    const state = reactive({
      type: route.query.type, // 类型
      knowledgePointIds: route.query.knowledgePointIds, // 智能组卷 多个编号
      lessonCoursewareId: route.query.lessonCoursewareId, // 教材编号
      studentUnitExaminationId: '', // 测验编号
      background: 'transparent',
      color: '#fff',
      visiableAnswer: false,
      examDetail: {} as any,
      currentIndex: 0,
      time: 0,
      questionList: [],
      visiableInfo: {
        show: false,
        operationType: 'RESULT' as 'RESULT' | 'BACK' | 'CONTINUE' | 'TIME',
        type: 'DEFAULT' as 'DEFAULT' | 'FAIL' | 'PASS' | 'GOOD' | 'COUNTDOWN',
        content: '',
        showCancelButton: false,
        confirmButtonText: '',
        cancelButtonText: '',
        title: ''
      },
      nextStatus: false,
      swipeHeight: 'auto' as any,
      countDownOver: false // 是否已显示时间倒计时
    });

    // 计时
    const countDownRef = useCountDown({
      // 倒计时 60 秒
      time: state.time,
      onChange(current: CurrentTime) {
        const diffTime = 5 * 60 * 1000;
        if (diffTime >= current.total && !state.countDownOver) {
          // 判断是否已经有弹窗 - 如果有弹窗也就不显示倒计时弹窗
          if (state.visiableInfo.show) {
            state.countDownOver = true;
            return;
          }
          state.visiableInfo.show = true;
          state.visiableInfo.title = '倒计时5分钟';
          state.visiableInfo.showCancelButton = false;
          state.visiableInfo.operationType = 'TIME';
          state.visiableInfo.type = 'COUNTDOWN';
          state.visiableInfo.confirmButtonText = '确认';
          state.visiableInfo.content = `距离交卷时间还剩五分钟哦，请尽快答题～`;
          state.countDownOver = true;
        }
      },
      onFinish: async () => {
        eventUnit.emit('unitAudioStop');
        await onResultPopup();
        onAfter();
      }
    });

    const getExamDetails = async () => {
      try {
        let temp: any = {};
        if (state.type === 'ai') {
          const { data } = await request.post(
            '/edu-app/studentUnitExamination/pointRandomSave',
            {
              data: {
                knowledgePointIds: state.knowledgePointIds
              }
            }
          );
          temp = data || {};
        } else {
          const { data } = await request.post(
            '/edu-app/studentUnitExamination/mockExamination',
            {
              data: {
                lessonCoursewareId: state.lessonCoursewareId
              }
            }
          );
          temp = data || {};
        }

        temp.examinationQuestionAdds.forEach((item: any) => {
          item.showAnalysis = false; // 默认不显示解析
          item.analysis = {
            message: item.answerAnalysis,
            topic: true, // 是否显示结果
            userResult: false // 用户答题对错
          };
          item.userAnswer = []; // 用户答题
        });
        state.questionList = temp.examinationQuestionAdds || [];
        state.studentUnitExaminationId = temp.unitExaminationId;
        state.examDetail = temp || {};
        calcTime();
      } catch {
        //
      }
    };

    /**
     * @description 计算考试时间剩余时间
     */
    const calcTime = async () => {
      const examDetail = state.examDetail || {};
      const timeMinutes = examDetail.timeMinutes || 0; // 测验时间
      state.time = Math.ceil(timeMinutes * 60 * 1000);
      setTimeout(() => {
        countDownRef.reset(timeMinutes * 60 * 1000);
        countDownRef.start();
      }, 10);
    };

    /**
     * @description 下一题 | 测试完成
     */
    const onNextQuestion = async () => {
      state.nextStatus = true;
      try {
        const questionList = state.questionList || [];
        const userAnswerList: any = []; // 所有题目的答案
        questionList.forEach((question: any, index: number) => {
          // 格式化所有题目的答案
          if (question.userAnswer && question.userAnswer.length > 0) {
            userAnswerList.push({
              questionId: question.id,
              details: question.userAnswer
            });
          }
        });

        // 判断是否是最后一题
        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.type = 'DEFAULT';
          state.visiableInfo.cancelButtonText = '再等等';
          state.visiableInfo.confirmButtonText = '确认完成';
          state.visiableInfo.content = `确认本次测验的题目都完成了吗？`;
          state.nextStatus = false;
          onAfter();
          return;
        }

        await request.post('/edu-app/studentUnitExamination/submitAnswer', {
          hideLoading: true,
          data: {
            answers: userAnswerList,
            studentUnitExaminationId: state.studentUnitExaminationId
          }
        });
        swipeRef.value?.next();
      } catch {
        //
      }
      state.nextStatus = false;
    };

    /**
     * @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) => {
            // console.log(img.complete);
            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;
        router.back();
        router.back();
      } else if (state.visiableInfo.operationType === 'BACK') {
        onResultPopup();
      } else if (state.visiableInfo.operationType === 'CONTINUE') {
        onResultPopup();
      } else if (state.visiableInfo.operationType === 'TIME') {
        state.visiableInfo.show = false;
      }
    };
    const onCloseResult = async (status: boolean) => {
      if (state.visiableInfo.operationType === 'BACK') {
        if (status) {
          state.visiableInfo.show = false;
          window.history.pushState(null, '', document.URL);
          window.addEventListener('popstate', onBack, false);
          return;
        }
        try {
          await request.get('/edu-app/studentUnitExamination/dropExamination', {
            params: {
              studentUnitExaminationId: state.studentUnitExaminationId
            }
          });
          state.visiableInfo.show = false;
          onAfter();
        } catch {
          //
        }
      } else if (state.visiableInfo.operationType === 'CONTINUE') {
        state.visiableInfo.show = false;
        window.history.pushState(null, '', document.URL);
        window.addEventListener('popstate', onBack, false);
      }
    };

    /** 结果页面弹窗 */
    const onResultPopup = async () => {
      try {
        const questionList = state.questionList || [];
        const userAnswerList: any = []; // 所有题目的答案
        questionList.forEach((question: any) => {
          // 格式化所有题目的答案
          if (question.userAnswer && question.userAnswer.length > 0) {
            userAnswerList.push({
              questionId: question.id,
              details: question.userAnswer
            });
          }
        });
        const { data } = await request.post(
          '/edu-app/studentUnitExamination/completionExamination',
          {
            hideLoading: false,
            data: {
              answers: userAnswerList,
              studentUnitExaminationId: state.studentUnitExaminationId
            }
          }
        );
        // 60 及格
        // 85 及以上优秀
        state.visiableInfo.show = true;
        state.visiableInfo.title = data.score + '分';
        state.visiableInfo.showCancelButton = false;
        state.visiableInfo.operationType = 'RESULT';
        state.visiableInfo.confirmButtonText = '确认';

        if (data.status === 'A_EXCELLENT') {
          state.visiableInfo.type = 'GOOD';
          state.visiableInfo.content = '<div>你很棒，题目掌握的非常不错，';
        } else if (data.status === 'B_PASS') {
          state.visiableInfo.type = 'PASS';
          state.visiableInfo.content = '<div>还需要加油哦，';
        } else {
          state.visiableInfo.type = 'FAIL';
          state.visiableInfo.content = '<div>别气馁，继续努力，';
        }
        state.visiableInfo.content += `您本次获得了<span class='${
          styles.right
        }'>${data.score}分</span>，正确率<span class='${styles.error}'>${
          data.rightRate
        }%</span>，实际用时<span class='${styles.minutes}'>${Math.ceil(
          data.answerTime / 60
        )}</span>分钟~</div>`;
      } catch {
        //
      }
    };

    // 拦截
    const onBack = () => {
      state.visiableInfo.show = true;
      state.visiableInfo.title = '确认要离开吗？';
      state.visiableInfo.showCancelButton = true;
      state.visiableInfo.operationType = 'BACK';
      state.visiableInfo.type = 'DEFAULT';
      state.visiableInfo.cancelButtonText = '弃考';
      state.visiableInfo.confirmButtonText = '提交';
      state.visiableInfo.content = `还有题目未完成哦，是否要提前交卷？`;
      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}>
                            <span>{state.currentIndex + 1}</span>/
                            {state.questionList.length}
                          </div>
                          <div class={styles.questionType}>
                            {countDownRef.current.value.minutes +
                              countDownRef.current.value.hours * 60}
                            :{countDownRef.current.value.seconds}
                          </div>
                        </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}>
                            <span>{state.currentIndex + 1}</span>/
                            {state.questionList.length}
                          </div>
                          <div class={styles.questionType}>
                            {countDownRef.current.value.minutes +
                              countDownRef.current.value.hours * 60}
                            :{countDownRef.current.value.seconds}
                          </div>
                        </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}>
                            <span>{state.currentIndex + 1}</span>/
                            {state.questionList.length}
                          </div>
                          <div class={styles.questionType}>
                            {countDownRef.current.value.minutes +
                              countDownRef.current.value.hours * 60}
                            :{countDownRef.current.value.seconds}
                          </div>
                        </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}>
                            <span>{state.currentIndex + 1}</span>/
                            {state.questionList.length}
                          </div>
                          <div class={styles.questionType}>
                            {countDownRef.current.value.minutes +
                              countDownRef.current.value.hours * 60}
                            :{countDownRef.current.value.seconds}
                          </div>
                        </div>
                      )
                    }}
                  </KeepLookQuestion>
                )}
                {item.questionTypeCode === QuestionType.PLAY && (
                  <PlayQuestion
                    v-model:value={item.userAnswer}
                    data={item}
                    index={index + 1}
                    unitId={state.studentUnitExaminationId as any}
                    showAnalysis={item.showAnalysis}
                    analysis={item.analysis}>
                    {{
                      title: () => (
                        <div class={styles.questionTitle}>
                          <div class={styles.questionNum}>
                            <span>{state.currentIndex + 1}</span>/
                            {state.questionList.length}
                          </div>
                          <div class={styles.questionType}>
                            {countDownRef.current.value.minutes +
                              countDownRef.current.value.hours * 60}
                            :{countDownRef.current.value.seconds}
                          </div>
                        </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}
            onSelect={(item: any) => {
              // 跳转，并且跳过动画
              swipeRef.value?.swipeTo(item, {
                immediate: true
              });
              state.visiableAnswer = false;
            }}
          />
        </ActionSheet>

        <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}
            closeable={
              state.visiableInfo.operationType === 'BACK' ? true : false
            }
            contentHtml
            onConform={onConfirmResult}
            onClose={onCloseResult}
          />
        </Popup>
      </div>
    );
  }
});
