package com.qmth.themis.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.themis.business.cache.ExamRecordCacheUtil;
import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dao.TEExamBreachLogMapper;
import com.qmth.themis.business.dto.MqDto;
import com.qmth.themis.business.entity.TBUser;
import com.qmth.themis.business.entity.TEExamBreachLog;
import com.qmth.themis.business.entity.TOeExamRecord;
import com.qmth.themis.business.enums.BreachCancelTypeEnum;
import com.qmth.themis.business.enums.BreachTypeEnum;
import com.qmth.themis.business.enums.MqTagEnum;
import com.qmth.themis.business.enums.SystemOperationEnum;
import com.qmth.themis.business.service.MqDtoService;
import com.qmth.themis.business.service.TEExamBreachLogService;
import com.qmth.themis.business.service.TEExamStudentService;
import com.qmth.themis.business.service.TOeExamRecordService;
import com.qmth.themis.business.util.MqUtil;
import com.qmth.themis.business.util.ServletUtil;
import com.qmth.themis.common.exception.BusinessException;
import com.qmth.themis.common.util.IpUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: 考生违纪处理 服务实现类
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/6/25
 */
@Service
public class TEExamBreachLogServiceImpl extends ServiceImpl<TEExamBreachLogMapper, TEExamBreachLog> implements TEExamBreachLogService {

    @Resource
    TOeExamRecordService tOeExamRecordService;

    @Resource
    TEExamBreachLogService teExamBreachLogService;

    @Resource
    TEExamStudentService teExamStudentService;

    @Resource
    MqUtil mqUtil;

    @Resource
    MqDtoService mqDtoService;

    /**
     * 违纪处理接口
     *
     * @param mapParameter
     */
    @Override
    @Transactional
    public void breachLogic(Map<String, Object> mapParameter) {
        List<String> recordIdList = (List<String>) mapParameter.get(SystemConstant.EXAM_RECORD_ID);
        String description = String.valueOf(mapParameter.get("description"));
        List<TOeExamRecord> tOeExamRecordList = new ArrayList<>();

        if (recordIdList.size() > 0) {
            Integer status = Integer.parseInt(String.valueOf(mapParameter.get(SystemConstant.STATUS)));
            TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
            List<TEExamBreachLog> teExamBreachLogList = new ArrayList<>();
            if (status.intValue() == 0) {//新建违纪
                BreachTypeEnum type = BreachTypeEnum.valueOf(String.valueOf(mapParameter.get(SystemConstant.TYPE)));
                List<TEExamBreachLog> finalTeExamBreachLogList = teExamBreachLogList;
                for (int i = 0; i < recordIdList.size(); i++) {
                    Long l = Long.parseLong(String.valueOf(recordIdList.get(i)));
                    Long examId = null, examStudentId = null, examActivityId = null;
                    TOeExamRecord tOeExamRecord = null;
                    if (Objects.isNull(ExamRecordCacheUtil.getId(l))) {
                        tOeExamRecord = tOeExamRecordService.getById(l);
                        examId = tOeExamRecord.getExamId();
                        examStudentId = tOeExamRecord.getExamStudentId();
                        examActivityId = tOeExamRecord.getExamActivityId();
                    } else {
                        examId = ExamRecordCacheUtil.getExamId(l);
                        examStudentId = ExamRecordCacheUtil.getExamStudentId(l);
                        examActivityId = ExamRecordCacheUtil.getExamActivityId(l);
                    }
                    TEExamBreachLog teExamBreachLog = new TEExamBreachLog(examId, examActivityId, l, examStudentId, type.name(), description, status);
                    teExamBreachLog.setCreateId(tbUser.getId());
                    finalTeExamBreachLogList.add(teExamBreachLog);
                    if (Objects.nonNull(ExamRecordCacheUtil.getId(l))) {
                        Integer breachStatus = Objects.nonNull(ExamRecordCacheUtil.getBreachStatus(l)) ? ExamRecordCacheUtil.getBreachStatus(l) : 1;
                        if (breachStatus.intValue() == 1) {
                            Long timestamp = System.currentTimeMillis();
                            ExamRecordCacheUtil.setBreachStatus(l, status, timestamp);
                            tOeExamRecordService.sendExamRecordDataSaveMq(l, timestamp);
                        }
                    } else {
                        Integer breachStatus = Objects.nonNull(tOeExamRecord.getBreachStatus()) ? tOeExamRecord.getBreachStatus() : 1;
                        if (breachStatus.intValue() == 1) {
                            tOeExamRecord.setBreachStatus(status);
                            tOeExamRecordList.add(tOeExamRecord);
                        }
                    }
                }
            } else {//撤销违纪
                Long breachLogId = Long.parseLong(String.valueOf(mapParameter.get("breachLogId")));
                BreachCancelTypeEnum type = BreachCancelTypeEnum.valueOf(String.valueOf(mapParameter.get(SystemConstant.TYPE)));
                TEExamBreachLog teExamBreachLog = teExamBreachLogService.getById(breachLogId);
                Optional.ofNullable(teExamBreachLog).orElseThrow(() -> new BusinessException("未找到违纪记录"));

                if (Objects.nonNull(teExamBreachLog.getStatus()) && teExamBreachLog.getStatus().intValue() == 1) {
                    throw new BusinessException("该条违纪信息已处理");
                }
                teExamBreachLog.setType(type.name());
                teExamBreachLog.setDescription(description);
                teExamBreachLog.setStatus(status);
                teExamBreachLog.setUpdateId(tbUser.getId());
                teExamBreachLogList.add(teExamBreachLog);
            }
            if (!CollectionUtils.isEmpty(tOeExamRecordList)) {
                tOeExamRecordService.saveOrUpdateBatch(tOeExamRecordList);
            }
            for (TEExamBreachLog eb : teExamBreachLogList) {
                Map<String, Object> properties = new HashMap<>();
                properties.put(SystemConstant.TYPE, eb.getDescription());
                properties.put(SystemConstant.REMARK, eb.getType());
                properties.put(SystemConstant.EXAM_STUDENT_ID, eb.getExamStudentId());
                properties.put(SystemConstant.EXAM_RECORD_ID, eb.getExamRecordId());
                properties.put(SystemConstant.OBJ_ID, eb.getId());
                properties.put(SystemConstant.BREACH_LOG_STATUS, status);
                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(eb.getExamStudentId());
                MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.STUDENT.name(), eb.getStatus() == 0 ? SystemOperationEnum.BREACH_HANDLE : SystemOperationEnum.BREACH_REVOKE, MqTagEnum.STUDENT, String.valueOf(examStudentCacheBean.getStudentId()), properties, IpUtil.getRemoteIp(ServletUtil.getRequest()));
                mqDtoService.assembleSendAsyncMsg(mqDto);
            }
            teExamBreachLogService.saveOrUpdateBatch(teExamBreachLogList);
        }
    }

    /**
     * 撤销违纪接口
     *
     * @param mapParameter
     */
    @Override
    @Transactional
    public void updateBreachStatus(Map<String, Object> mapParameter) {
        List<String> recordIdList = (List<String>) mapParameter.get(SystemConstant.EXAM_RECORD_ID);
        Integer status = Integer.parseInt(String.valueOf(mapParameter.get(SystemConstant.STATUS)));
        List<TOeExamRecord> tOeExamRecordList = new ArrayList<>();

        for (int i = 0; i < recordIdList.size(); i++) {
            Long l = Long.parseLong(String.valueOf(recordIdList.get(i)));
            QueryWrapper<TEExamBreachLog> teExamBreachLogQueryWrapper = new QueryWrapper<>();
            teExamBreachLogQueryWrapper.lambda().eq(TEExamBreachLog::getExamRecordId, l)
                    .eq(TEExamBreachLog::getStatus, 0);
            int count = teExamBreachLogService.count(teExamBreachLogQueryWrapper);
            if (count == 0) {//撤销违纪都处理完了这个考生的考试记录里的违纪才算取消
                TOeExamRecord tOeExamRecord = null;
                if (Objects.isNull(ExamRecordCacheUtil.getId(l))) {
                    tOeExamRecord = tOeExamRecordService.getById(l);
                    tOeExamRecord.setBreachStatus(status);
                    tOeExamRecordList.add(tOeExamRecord);
                } else {
                    Long timestamp = System.currentTimeMillis();
                    ExamRecordCacheUtil.setBreachStatus(l, status, timestamp);
                    tOeExamRecordService.sendExamRecordDataSaveMq(l, timestamp);
                }
            }
        }
        if (!CollectionUtils.isEmpty(tOeExamRecordList)) {
            tOeExamRecordService.saveOrUpdateBatch(tOeExamRecordList);
        }
    }
}
