package com.ruoyi.hezhi.service.impl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.hezhi.domain.*;
import com.ruoyi.hezhi.domain.dto.MemberExamSimulateAllDTO;
import com.ruoyi.hezhi.mapper.*;
import com.ruoyi.hezhi.service.ITbExamService;
import com.ruoyi.hezhi.service.ITbExamSimulateInfoService;
import com.ruoyi.hezhi.service.ITbExamSubjectAnswerService;
import com.ruoyi.hezhi.service.ITbExamSubjectService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考试、模拟考试考生详情Service业务层处理
 *
 * @author ruoyi
 * @date 2024-11-11
 */
@Service
public class TbExamSimulateInfoServiceImpl implements ITbExamSimulateInfoService
{
    @Autowired
    private TbExamSimulateInfoMapper tbExamSimulateInfoMapper;
    @Autowired
    private TbSubjectWarehouseClassMapper tbSubjectWarehouseClassMapper;
    @Autowired
    private TbExamSubjectSimulateMapper tbExamSubjectSimulateMapper;
    @Autowired
    private TbExamMapper examMapper;
    @Autowired
    private TbExamBatchMapper tbExamBatchMapper;
    @Autowired
    private TbExamSubjectMapper tbExamSubjectMapper;
    @Autowired
    private TbMemberExamSimulateAllMapper tbMemberExamSimulateAllMapper;
    @Autowired
    private TbMemberSubjectCollectMapper tbMemberSubjectCollectMapper;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private ITbExamSubjectService tbExamSubjectService;
    @Autowired
    private ITbExamService examService;
    @Autowired
    private ITbExamSubjectAnswerService tbExamSubjectAnswerService;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private TbExamRegistrationMapper tbExamRegistrationMapper;

    /**
     * 查询考试、模拟考试考生详情
     *
     * @param examSimulateInfoId 考试、模拟考试考生详情主键
     * @return 考试、模拟考试考生详情
     */
    @Override
    public TbExamSimulateInfo selectTbExamSimulateInfoByExamSimulateInfoId(Long examSimulateInfoId)
    {
        return tbExamSimulateInfoMapper.selectTbExamSimulateInfoByExamSimulateInfoId(examSimulateInfoId);
    }

    /**
     * 查询考试、模拟考试考生详情列表
     *
     * @param tbExamSimulateInfo 考试、模拟考试考生详情
     * @return 考试、模拟考试考生详情
     */
    @Override
    public List<TbExamSimulateInfo> selectTbExamSimulateInfoList(TbExamSimulateInfo tbExamSimulateInfo)
    {
        return tbExamSimulateInfoMapper.selectTbExamSimulateInfoList(tbExamSimulateInfo);
    }

    /**
     * 新增考试、模拟考试考生详情
     *
     * @param tbExamSimulateInfo 考试、模拟考试考生详情
     * @return 结果
     */
    @Override
    public int insertTbExamSimulateInfo(TbExamSimulateInfo tbExamSimulateInfo)
    {
        tbExamSimulateInfo.setCreateTime(DateUtils.getNowDate());
        return tbExamSimulateInfoMapper.insertTbExamSimulateInfo(tbExamSimulateInfo);
    }

    /**
     * 修改考试、模拟考试考生详情
     *
     * @param tbExamSimulateInfo 考试、模拟考试考生详情
     * @return 结果
     */
    @Override
    public int updateTbExamSimulateInfo(TbExamSimulateInfo tbExamSimulateInfo)
    {
        tbExamSimulateInfo.setUpdateTime(DateUtils.getNowDate());
        return tbExamSimulateInfoMapper.updateTbExamSimulateInfo(tbExamSimulateInfo);
    }

    /**
     * 批量删除考试、模拟考试考生详情
     *
     * @param examSimulateInfoIds 需要删除的考试、模拟考试考生详情主键
     * @return 结果
     */
    @Override
    public int deleteTbExamSimulateInfoByExamSimulateInfoIds(Long[] examSimulateInfoIds)
    {
        return tbExamSimulateInfoMapper.deleteTbExamSimulateInfoByExamSimulateInfoIds(examSimulateInfoIds);
    }

    /**
     * 删除考试、模拟考试考生详情信息
     *
     * @param examSimulateInfoId 考试、模拟考试考生详情主键
     * @return 结果
     */
    @Override
    public int deleteTbExamSimulateInfoByExamSimulateInfoId(Long examSimulateInfoId)
    {
        return tbExamSimulateInfoMapper.deleteTbExamSimulateInfoByExamSimulateInfoId(examSimulateInfoId);
    }

    /**
     * 查询模拟考试考生及考试信息
     *
     * @param params 参数
     * @return 结果
     */
    @Override
    public Map<String,Object> getSimulateSubjectAllInfo(Map<String, Object> params) {
        long memberUserId = Long.parseLong(params.get("memberUserId").toString());
        long courseId = Long.parseLong(params.get("courseId").toString());
        long subjectWarehouseClassId = Long.parseLong(params.get("subjectWarehouseClassId").toString());
        Map<String, Object> simulateInfo = tbExamSimulateInfoMapper.getSimulateSubjectAllInfo(params);

        // 查询模拟考试题目
        List<TbExamSubject> examSubjectList = tbExamSubjectMapper.getExamSubjectList(null, subjectWarehouseClassId);

        if (!examSubjectList.isEmpty()) {
            TbSubjectWarehouseClass subjectWarehouseClass = tbSubjectWarehouseClassMapper.selectTbSubjectWarehouseClassBySubjectWarehouseClassId(subjectWarehouseClassId);

            TbExamSimulateInfo examSimulateInfo = new TbExamSimulateInfo();
            examSimulateInfo.setExamPlatformNumber(String.valueOf(new Random().nextInt(999) + 1));// 生成1到999的随机数
            examSimulateInfo.setMemberUserId(memberUserId);
            examSimulateInfo.setSubjectWarehouseClassId(subjectWarehouseClassId);
            examSimulateInfo.setExamType(2);
            examSimulateInfo.setExamMinute(subjectWarehouseClass.getSimulationExamMinute());

            String nowTime = DateUtils.getTime();
            examSimulateInfo.setStartTime(nowTime);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Calendar calendar = Calendar.getInstance();
            try {
                calendar.setTime(sdf.parse(nowTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            calendar.add(Calendar.MINUTE, subjectWarehouseClass.getSimulationExamMinute()); // 添加分钟数
            examSimulateInfo.setEndTime(sdf.format(calendar.getTime()));
            examSimulateInfo.setExamStatus(1);
            examSimulateInfo.setCompleteStatus(1);

            examSimulateInfo.setTotalScore(subjectWarehouseClass.getTotalScore());
            examSimulateInfo.setPassScore(subjectWarehouseClass.getPassScore());
            if (simulateInfo == null) {
                examSimulateInfo.setCreateTime(DateUtils.getNowDate());
                tbExamSimulateInfoMapper.insertTbExamSimulateInfo(examSimulateInfo);
            } else {

                // 定义时间格式
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                // 时间字符串
                String endTime = simulateInfo.get("endTime").toString();
                // 将字符串转换为Date
                Date timeToCompare = null;
                try {
                    timeToCompare = dateFormat.parse(endTime);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                // 获取当前时间
                Date currentTime = new Date();

                // 比较时间
                if (currentTime.after(timeToCompare)) {
                    TbExamSimulateInfo updateExamSimulateInfo = new TbExamSimulateInfo();
                    updateExamSimulateInfo.setExamSimulateInfoId(Long.parseLong(simulateInfo.get("examSimulateInfoId").toString()));
                    updateExamSimulateInfo.setExamStatus(2);
                    updateExamSimulateInfo.setCompleteStatus(2);
                    tbExamSimulateInfoMapper.updateTbExamSimulateInfo(updateExamSimulateInfo);
                    updateExamSimulateInfo.setCreateTime(DateUtils.getNowDate());
                    tbExamSimulateInfoMapper.insertTbExamSimulateInfo(examSimulateInfo);
                }
            }

        }

        return tbExamSimulateInfoMapper. getSimulateSubjectAllInfo(params);
    }

    /**
     * 考试交卷
     *
     * @param memberExamSimulateAllDTO
     * @return ok
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult subjectExamSubmit(MemberExamSimulateAllDTO memberExamSimulateAllDTO) {
        Date endTime = new Date();
        TbExamSimulateInfo examSimulateInfo = tbExamSimulateInfoMapper.selectTbExamSimulateInfoByExamSimulateInfoId(memberExamSimulateAllDTO.getExamSimulateInfoId());
        if (examSimulateInfo == null) {
            return AjaxResult.error("考试详情异常");
        }
        if (examSimulateInfo.getPassStatus() != 0) {
            return AjaxResult.error("已交卷，请勿重复提交");
        }
        // 总分
        BigDecimal countTotalScore = tbExamSimulateInfoMapper.countTotalScore(memberExamSimulateAllDTO.getExamSimulateInfoId());
        // 及格分
        BigDecimal passScore = examSimulateInfo.getPassScore();
        int submitStatus = 1;
        if (examSimulateInfo.getExamType() == 1) {
            submitStatus = memberExamSimulateAllDTO.getSubmitStatus();
        }


        TbExamSimulateInfo simulateInfo = new TbExamSimulateInfo();
        simulateInfo.setExamSimulateInfoId(examSimulateInfo.getExamSimulateInfoId());
        simulateInfo.setCompleteStatus(2);
        simulateInfo.setExamStatus(2);
        simulateInfo.setSubmitStatus(submitStatus);
        simulateInfo.setCompleteScore(countTotalScore);
        simulateInfo.setCompleteTime(DateUtils.getTime());
        //查出考试报名表对应的数据
        TbExamRegistration tbExamRegistration = tbExamRegistrationMapper.selectTbExamRegistrationByUserIdExamId(examSimulateInfo.getMemberUserId(), examSimulateInfo.getExamId());


        if (countTotalScore.compareTo(passScore) >= 0) {
            simulateInfo.setPassStatus(1);
            if (ObjectUtils.isNotEmpty(tbExamRegistration)) {//能查出来说明是正式考试，再修改考试报名的状态，查不出说明是模拟考试，不修改
                tbExamRegistration.setExamineStatus(1);
            }

        } else {
            simulateInfo.setPassStatus(2);
            if (ObjectUtils.isNotEmpty(tbExamRegistration)) {
                tbExamRegistration.setExamineStatus(2);
            }
        }
        if (ObjectUtils.isNotEmpty(tbExamRegistration)) {
            tbExamRegistrationMapper.updateTbExamRegistration(tbExamRegistration);
        }
        tbExamSimulateInfoMapper.updateTbExamSimulateInfo(simulateInfo);
        TbExamSimulateInfo tbExamSimulateInfo = tbExamSimulateInfoMapper.selectTbExamSimulateInfoByExamSimulateInfoIdRetain(memberExamSimulateAllDTO.getExamSimulateInfoId());
        //计算耗时
        if (StringUtils.isNotNull(tbExamSimulateInfo)&&StringUtils.isNotEmpty(tbExamSimulateInfo.getStartTime())) {
            String usageTime = DateUtils.timeDistanceSecond(endTime, DateUtils.parseDate(tbExamSimulateInfo.getStartTime()));
            tbExamSimulateInfo.setUsageTime(usageTime);
        }
        return AjaxResult.success().put("data",tbExamSimulateInfo);
    }

    /**
     * 交卷 转换答题卡
     * @param memberUserId 用户DI
     * @param examSimulateInfoId 考生ID
     * @param exam 考试
     * @param memberExamSimulateAllList 答题列表
     * @return 结果
     */
    public List<TbMemberExamSimulateAll> transferMemberExamSimulateAll(Long memberUserId, Long examSimulateInfoId, TbExam exam, List<MemberExamSimulateAllDTO> memberExamSimulateAllList){
        ArrayList<TbMemberExamSimulateAll> resultList = new ArrayList<>();
        if (!memberExamSimulateAllList.isEmpty()){
            for (MemberExamSimulateAllDTO examSimulateAllDTO : memberExamSimulateAllList) {
                Long examSubjectId = examSimulateAllDTO.getExamSubjectId();
                String myAnswer = examSimulateAllDTO.getMyAnswer();
                Long location = examSimulateAllDTO.getLocation();

                // 查询当前题目
                TbExamSubject tbExamSubject = tbExamSubjectService.selectTbExamSubjectByExamSubjectId(examSubjectId);

                HashMap<String, Object> params = new HashMap<>();
                params.put("memberUserId", memberUserId);
                params.put("examSubjectId", examSubjectId);

                // 正确答案
                String answer = tbExamSubject.getAnswer();
                if (tbExamSubject.getSubjectType() == 3) {
                    if ("正确".equals(answer)) {
                        answer = "A";
                    }
                    if ("错误".equals(answer)) {
                        answer = "B";
                    }
                }

                BigDecimal score = new BigDecimal(0);
                // 题目分数
                if (tbExamSubject.getSubjectType() == 1) {
                    score = exam.getSingleSelectScore();
                } else if (tbExamSubject.getSubjectType() == 2) {
                    score = exam.getManySelectScore();
                } else if (tbExamSubject.getSubjectType() == 3) {
                    score = exam.getJudgeScore();
                } else if (tbExamSubject.getSubjectType() == 4) {
                    score = exam.getDiscussScore();
                }

                TbMemberExamSimulateAll memberExamSimulateAll = new TbMemberExamSimulateAll();
                memberExamSimulateAll.setExamSimulateInfoId(examSimulateInfoId);
                memberExamSimulateAll.setExamSubjectId(examSubjectId);
                memberExamSimulateAll.setMemberUserId(memberUserId);
                memberExamSimulateAll.setLocation(location);
                memberExamSimulateAll.setMyAnswer(myAnswer);
                memberExamSimulateAll.setAnswer(answer);
                memberExamSimulateAll.setSubjectType(tbExamSubject.getSubjectType());
                memberExamSimulateAll.setExamType(1);

                if (tbExamSubject.getSubjectType() != 4) {
                    if (myAnswer.equals(answer)) {
                        memberExamSimulateAll.setStatus(1);
                        memberExamSimulateAll.setScore(score);
                    } else {
                        memberExamSimulateAll.setStatus(2);
                        memberExamSimulateAll.setScore(new BigDecimal(0));
                    }
                } else {
                    // 论述
                    BigDecimal discussScore = tbExamSubjectAnswerService.getDiscussScore(tbExamSubject.getExamSubjectNo(), myAnswer);
                    if (discussScore.compareTo(score) > 0) {
                        memberExamSimulateAll.setScore(score);
                    } else {
                        memberExamSimulateAll.setScore(discussScore);
                    }
                    memberExamSimulateAll.setStatus(3);
                }


                memberExamSimulateAll.setCreateTime(DateUtils.getNowDate());
                memberExamSimulateAll.setDelFlag(0);
                resultList.add(memberExamSimulateAll);
            }
        }
        return resultList;
    }

    /**
     * 计算总分
     *
     * @param examSimulateInfoId 考试、模拟考试考生详情主键
     * @return 结果
     */
    @Override
    public BigDecimal countTotalScore(Long examSimulateInfoId) {
        return tbExamSimulateInfoMapper.countTotalScore(examSimulateInfoId);
    }

    /**
     * 查询正式考试考生及考试信息
     *
     * @param params 参数
     * @return 结果
     */
    @Override
    public Map<String, Object> getFormalSubjectAllInfo(Map<String, Object> params) {
        long memberUserId = Long.parseLong(params.get("memberUserId").toString());
        long examId = Long.parseLong(params.get("examId").toString());

        Map<String, Object> formalSubjectAllInfo = tbExamSimulateInfoMapper.getFormalSubjectAllInfo(params);

        TbExam tbExam = examMapper.selectTbExamByExamId(examId);
        if (tbExam != null && formalSubjectAllInfo == null) {
            TbExamSimulateInfo examSimulateInfo = new TbExamSimulateInfo();
            Integer platformNumber = tbExamSimulateInfoMapper.selectMaxExamPlatformNumber(examId);
            examSimulateInfo.setExamPlatformNumber(String.valueOf(platformNumber + 1));
            examSimulateInfo.setMemberUserId(memberUserId);
            examSimulateInfo.setExamId(examId);
            examSimulateInfo.setExamType(1);
            examSimulateInfo.setExamMinute(tbExam.getExamMinute());
            examSimulateInfo.setTotalScore(tbExam.getTotalScore());
            examSimulateInfo.setPassScore(tbExam.getPassScore());
            examSimulateInfo.setExamStatus(1);
            examSimulateInfo.setCompleteStatus(1);
            examSimulateInfo.setIsAgain(0);
            examSimulateInfo.setCreateTime(DateUtils.getNowDate());
            tbExamSimulateInfoMapper.insertTbExamSimulateInfo(examSimulateInfo);
        }

        return tbExamSimulateInfoMapper.getFormalSubjectAllInfo(params);
    }

    /**
     * 正式考试补考
     *
     * @param memberExamSimulateAllDTO
     * @return ok
     */
    @Override
    public AjaxResult subjectFormalAgain(MemberExamSimulateAllDTO memberExamSimulateAllDTO) {
        long memberUserId = memberExamSimulateAllDTO.getMemberUserId();
        long examId = memberExamSimulateAllDTO.getExamId();

        HashMap<String, Object> params = new HashMap<>();
        params.put("memberUserId", memberUserId);
        params.put("examId", examId);
        Map<String, Object> formalSubjectAllInfo = tbExamSimulateInfoMapper.getFormalSubjectAllInfo(params);

        if (formalSubjectAllInfo == null) {
            return AjaxResult.error("未进行考试，不允许补考");
        }
        if (!"2".equals(formalSubjectAllInfo.get("passStatus").toString())) {
            return AjaxResult.error("您已通过，无需补考");
        }
        if ("1".equals(formalSubjectAllInfo.get("isAgain").toString())) {
            //AjaxResult.error("您的补考次数已用完，请线下联系"+formalSubjectAllInfo.get("teacherName").toString()+formalSubjectAllInfo.get("teacherPhone").toString());
            Map<String,String> remap = new HashMap<>();
            remap.put("agencyName",formalSubjectAllInfo.get("agencyName").toString());//agencyName
            remap.put("teacherName",formalSubjectAllInfo.get("teacherName").toString());//teacherName
            remap.put("teacherPhone",formalSubjectAllInfo.get("teacherPhone").toString());//teacherPhone
            remap.put("reason","您的补考次数已用完");
            return AjaxResult.success(remap);
        }

        TbExam tbExam = examMapper.selectTbExamByExamId(examId);
        if (tbExam != null) {
            Integer isAgain = MapUtils.getInteger(formalSubjectAllInfo, "isAgain");
            if (isAgain == 0){
                TbExamRegistration tbExamRegistration = tbExamRegistrationMapper.selectTbExamRegistrationByUserIdExamId(memberUserId, examId);
                List<TbExamBatch> enableByExamId = tbExamBatchMapper.getEnableByExamId(examId, tbExam.getExamBatchEarly());
                if (!enableByExamId.isEmpty()){
                    List<TbExamBatch> collect = enableByExamId.stream().filter(item -> item.getBatchIndex() > tbExamRegistration.getExamBatchIndex()).collect(Collectors.toList());
                    if (!collect.isEmpty()){
                        TbExamBatch tbExamBatch = collect.get(0);
                        tbExamRegistration.setExamBatchIndex(tbExamBatch.getBatchIndex().intValue());
                        tbExamRegistration.setRegistrationBatch(tbExamBatch.getExamBatch());
                        tbExamRegistrationMapper.updateTbExamRegistration(tbExamRegistration);

                        isAgain = 1;
                    }else{
                        Map<String,String> remap = new HashMap<>();
                        remap.put("agencyName",formalSubjectAllInfo.get("agencyName").toString());//agencyName
                        remap.put("teacherName",formalSubjectAllInfo.get("teacherName").toString());//teacherName
                        remap.put("teacherPhone",formalSubjectAllInfo.get("teacherPhone").toString());//teacherPhone
                        remap.put("reason","该考试暂无下一批次");
                        return AjaxResult.success(remap);
                    }
                }else{
                    Map<String,String> remap = new HashMap<>();
                    remap.put("agencyName",formalSubjectAllInfo.get("agencyName").toString());//agencyName
                    remap.put("teacherName",formalSubjectAllInfo.get("teacherName").toString());//teacherName
                    remap.put("teacherPhone",formalSubjectAllInfo.get("teacherPhone").toString());//teacherPhone
                    remap.put("reason","该考试暂无下一批次");
                    return AjaxResult.success(remap);
                }
            }

            TbExamSimulateInfo examSimulateInfo = new TbExamSimulateInfo();
            Integer platformNumber = tbExamSimulateInfoMapper.selectMaxExamPlatformNumber(examId);
            examSimulateInfo.setExamPlatformNumber(String.valueOf(platformNumber + 1));
            examSimulateInfo.setMemberUserId(memberUserId);
            examSimulateInfo.setExamId(examId);
            examSimulateInfo.setExamType(1);
            examSimulateInfo.setExamMinute(tbExam.getExamMinute());
            examSimulateInfo.setTotalScore(tbExam.getTotalScore());
            examSimulateInfo.setPassScore(tbExam.getPassScore());
            examSimulateInfo.setExamStatus(1);
            examSimulateInfo.setCompleteStatus(1);
            examSimulateInfo.setIsAgain(isAgain);
            examSimulateInfo.setCreateTime(DateUtils.getNowDate());
            tbExamSimulateInfoMapper.insertTbExamSimulateInfo(examSimulateInfo);
        }
        return AjaxResult.success();
    }
}
