package com.ruoyi.sim.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.sim.domain.vo.RealExamFaultVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sim.mapper.RealExamFaultMapper;
import com.ruoyi.sim.domain.RealExamFault;
import org.springframework.transaction.annotation.Transactional;

/**
 * 考试故障关联Service业务层处理
 *
 * @author tom
 * @date 2024-12-15
 */
@Service
public class RealExamFaultService {
    @Autowired
    private RealExamFaultMapper realExamFaultMapper;
    @Autowired
    private FaultService faultService;

    /**
     * 查询考试故障关联
     *
     * @param refId 考试故障关联主键
     * @return 考试故障关联
     */
    public RealExamFault selectRealExamFaultByRefId(Long refId) {
        return realExamFaultMapper.selectRealExamFaultByRefId(refId);
    }

    /**
     * 查询考试故障关联列表
     *
     * @param realExamFault 考试故障关联
     * @return 考试故障关联
     */
    public List<RealExamFault> selectRealExamFaultList(RealExamFault realExamFault) {
        return realExamFaultMapper.selectRealExamFaultList(realExamFault);
    }

    /**
     * 新增考试故障关联
     *
     * @param realExamFault 考试故障关联
     * @return 结果
     */
    public int insertRealExamFault(RealExamFault realExamFault) {
        realExamFault.setCreateTime(DateUtils.getNowDate());
        return realExamFaultMapper.insertRealExamFault(realExamFault);
    }

    /**
     * 修改考试故障关联
     *
     * @param realExamFault 考试故障关联
     * @return 结果
     */
    @Transactional
    public int updateRealExamFault(RealExamFault realExamFault) {
        realExamFault.setUpdateTime(DateUtils.getNowDate());
        return realExamFaultMapper.updateRealExamFault(realExamFault);
    }

    /**
     * 批量删除考试故障关联
     *
     * @param refIds 需要删除的考试故障关联主键
     * @return 结果
     */
    public int deleteRealExamFaultByRefIds(Long[] refIds) {
        return realExamFaultMapper.deleteRealExamFaultByRefIds(refIds);
    }

    /**
     * 删除考试故障关联信息
     *
     * @param refId 考试故障关联主键
     * @return 结果
     */
    public int deleteRealExamFaultByRefId(Long refId) {
        return realExamFaultMapper.deleteRealExamFaultByRefId(refId);
    }

    // -------------------------------- tom add  --------------------------------

    private static final Logger l = LoggerFactory.getLogger(RealExamFaultService.class);

    /**
     * 初始化状态的 关联列表。
     *
     * @param examId
     * @return
     */
    public List<RealExamFault> listAllType2InitStateByExamId(Long examId) {
        RealExamFault q = new RealExamFault();
        q.setExamId(examId);
        q.setRefType(RealExamFault.Type.TYPE_2);
        q.setRefState(RealExamFault.State.INIT);
        return realExamFaultMapper.selectRealExamFaultList(q);
    }

    /**
     * reset real_exam_fault 表中关联数据
     * @param examId
     */
    @Transactional
    public void resetAllType2(Long examId) {
        listAllType2(examId)
                .stream()
                .forEach(ref -> {
                    ref.setRefState(RealExamFault.State.INIT);
                    ref.setAnswerRight(RealExamFault.AnswerRight.UNKNOWN);
                    ref.setChoiceQuestionValue("");
                    ref.setChoiceAnswerValue("");
                    ref.setSimFaultQuestionValue("");
                    ref.setSimFaultAnswerValue("");
                    ref.setMinus(0L);
                    updateRealExamFault(ref);
                });
    }

    public List<RealExamFault> listAllType2LoopReadStateByExamId(Long examId) {
        RealExamFault q = new RealExamFault();
        q.setExamId(examId);
        q.setRefType(RealExamFault.Type.TYPE_2);
        q.setRefState(RealExamFault.State.LOOP_READ);
        return realExamFaultMapper.selectRealExamFaultList(q);
    }

    public List<RealExamFault> listAllType2(Long examId) {
        RealExamFault q = new RealExamFault();
        q.setExamId(examId);
        q.setRefType(RealExamFault.Type.TYPE_2);
        return realExamFaultMapper.selectRealExamFaultList(q);
    }

    /**
     * 全部下发Ok?
     *
     * @param examId
     * @return
     */
    public boolean isAllType2StateXiaFa(long examId) {
        List<RealExamFault> list = listAllType2(examId);
        for (RealExamFault ref : list) {
            String state = ref.getRefState();
            if (RealExamFault.State.WRITTEN.equals(state) || RealExamFault.State.LOOP_READ.equals(state)) {
                continue;
            } else {
                return false;
            }
        }
        return true;
    }

    public boolean isState(Long refId, String state) {
        RealExamFault f = selectRealExamFaultByRefId(refId);
        if (f == null) {
            return false;
        }
        return state.equals(f.getRefState());
    }

    @Transactional
    public void calculateMinusByRealExamId(long examId) {
        l.info("calculateMinusByRealExamId realExamId : {}", examId);
        RealExamFault q = new RealExamFault();
        q.setExamId(examId);
        selectRealExamFaultList(q).forEach(ref -> {
            calculateMinus(ref.getRefId());
        });
    }

    /**
     * 计算减分。
     *
     * @param refId
     */
    @Transactional
    public void calculateMinus(Long refId) {
        l.info("calculate refId : {}", refId);
        RealExamFault f = selectRealExamFaultByRefId(refId);
        if (f == null) {
            throw new RuntimeException("calculateMinus");
        }
        if (!RealExamFault.Flag.YES.equals(f.getFlag())) {
            // throw new RuntimeException("calculateMinus");
            l.warn("not yes");
            return;
        }
        int minus = 0;
        String answerRight = RealExamFault.AnswerRight.UNKNOWN;
        l.info("f = {}", f);

        if (RealExamFault.Type.TYPE_1.equals(f.getRefType())) {
            // todo:选择题的算减分
            final String q = f.getChoiceQuestionValue();
            final String a = f.getChoiceAnswerValue();
        } else if (RealExamFault.Type.TYPE_2.equals(f.getRefType())) {
            final String q = f.getSimFaultQuestionValue();
            final String a = f.getSimFaultAnswerValue();
            // 模拟器故障的算减分
            if (StringUtils.isAllBlank(q, a)) {
                // todo:不应该出现的情况
                minus = 25;
                answerRight = RealExamFault.AnswerRight.NO;
            } else {
                if (!StringUtils.equals(q, a)) {
                    // 扣0分
                    minus = 0;
                    answerRight = RealExamFault.AnswerRight.YES;
                } else {
                    // 扣25分 故障未排除
                    minus = 25;
                    answerRight = RealExamFault.AnswerRight.NO;
                }
            }
        }
        f.setMinus((long) minus);
        f.setAnswerRight(answerRight);
        // 更新减分数据。
        updateRealExamFault(f);
    }

    public List<RealExamFaultVo> getReportListPart1(Long examId) {
        RealExamFault q = new RealExamFault();
        q.setExamId(examId);
        q.setRefType(RealExamFault.Type.TYPE_2);
        q.setFlag(RealExamFault.Flag.YES);
        List<RealExamFault> list1 = selectRealExamFaultList(q);
        List<RealExamFaultVo> list2 = new ArrayList<>();
        list1.forEach(ref -> {
            RealExamFaultVo vo = new RealExamFaultVo();
            BeanUtils.copyProperties(ref, vo);
            vo.setFault(faultService.selectFaultByFaultId(ref.getFaultId()));
            list2.add(vo);
        });
        return list2;
    }


}
