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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.themis.business.bean.admin.ExamInfoBean;
import com.qmth.themis.business.cache.RedisKeyHelper;
import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dao.TEExamStudentMapper;
import com.qmth.themis.business.dto.MarkResultSimpleExportDto;
import com.qmth.themis.business.dto.response.MarkResultDto;
import com.qmth.themis.business.dto.response.RoomCodeQueryDto;
import com.qmth.themis.business.dto.response.TEExamStudentDto;
import com.qmth.themis.business.entity.TEExamStudent;
import com.qmth.themis.business.service.TEExamStudentService;
import com.qmth.themis.business.util.RedisUtil;
import com.qmth.themis.common.util.GsonUtil;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @Description: 考生库 服务实现类
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/6/25
 */
@Service
public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, TEExamStudent>
        implements TEExamStudentService {

    @Resource
    TEExamStudentMapper teExamStudentMapper;

    @Resource
    RedisUtil redisUtil;

    /**
     * 查询考生信息
     *
     * @param iPage
     * @param examId
     * @param examActivityId
     * @param identity
     * @param name
     * @param roomCode
     * @param courseCode
     * @param grade
     * @param enable
     * @param classNo
     * @return
     */
    @Override
    public IPage<TEExamStudentDto> examStudentQuery(IPage<Map> iPage, Long examId, Long examActivityId, String identity,
                                                    String name, String roomCode, String courseCode, String grade, Integer enable, String classNo,
                                                    Integer hasPhoto) {
        return teExamStudentMapper
                .examStudentQuery(iPage, examId, examActivityId, identity, name, roomCode, courseCode, grade, enable,
                        classNo, hasPhoto);
    }

    @Cacheable(value = "exam_student", key = "#examStudentId", unless = "#result == null")
    @Override
    public ExamStudentCacheBean getExamStudentCacheBean(Long examStudentId) {
        return cacheOperation(examStudentId);
    }

    /**
     * 更新考生缓存
     *
     * @param examStudentId
     * @return
     */
    @Override
    @CachePut(value = "exam_student", key = "#examStudentId", condition = "#result != null")
    public ExamStudentCacheBean updateExamStudentCacheBean(Long examStudentId) {
        return cacheOperation(examStudentId);
    }

    /**
     * 删除考生缓存
     *
     * @param examStudentId
     */
    @Override
    @CacheEvict(value = "exam_student", key = "#examStudentId")
    public void deleteExamStudentCacheBean(Long examStudentId) {

    }

    /**
     * 考场查询
     *
     * @param roomName
     * @return
     */
    @Override
    public List<RoomCodeQueryDto> examRoomQuery(String roomName) {
        return teExamStudentMapper.examRoomQuery(roomName);
    }

    /**
     * 缓存操作
     *
     * @param examStudentId
     * @return
     */
    public ExamStudentCacheBean cacheOperation(Long examStudentId) {
        ExamStudentCacheBean ret = null;
        TEExamStudent es = getById(examStudentId);
        if (es == null) {
            return ret;
        }
//        if (es.getEnable() != null && es.getEnable().intValue() == 0) {
//            return ret;
//        }
        ret = new ExamStudentCacheBean();
        ret.setId(es.getId());
        ret.setExamId(es.getExamId());
        ret.setExamActivityId(es.getExamActivityId());
        ret.setStudentId(es.getStudentId());
        ret.setCourseCode(es.getCourseCode());
        ret.setCourseName(es.getCourseName());
        ret.setRoomCode(es.getRoomCode());
        ret.setRoomName(es.getRoomName());
        ret.setAlreadyExamCount(es.getAlreadyExamCount());
        ret.setCurrentRecordId(es.getCurrentRecordId());
        ret.setIdentity(es.getIdentity());
        ret.setName(es.getName());
        ret.setEnable(es.getEnable());
        ret.setClassNo(es.getClassNo());
        return ret;
    }

    @Transactional
    @Override
    public void updateByMqMsg(Map<String, Object> param) {
        Long examStudentId = (Long) param.get(SystemConstant.EXAM_STUDENT_ID);
        Integer alreadyExamCount = (Integer) param.get("alreadyExamCount");
        Long currentRecordId = (Long) param.get("currentRecordId");
        if (Objects.nonNull(alreadyExamCount) && Objects.nonNull(currentRecordId)) {
            teExamStudentMapper.updateAlreadyExamCountAndCurrentRecordId(examStudentId, alreadyExamCount, currentRecordId);
        } else if (Objects.nonNull(alreadyExamCount)) {
            teExamStudentMapper.updateAlreadyExamCount(examStudentId, alreadyExamCount);
        } else if (Objects.nonNull(currentRecordId)) {
            teExamStudentMapper.updateCurrentRecordId(examStudentId, currentRecordId);
        }
    }

    /**
     * 查询学生成绩信息
     *
     * @param iPage
     * @param examId
     * @param examActivityId
     * @param identity
     * @param name
     * @param courseCode
     * @return
     */
    @Override
    public IPage<MarkResultDto> markResultQuery(IPage<Map> iPage, Long examId, Long examActivityId, String identity,
                                                String name, String courseCode) {
        return teExamStudentMapper.markResultQuery(iPage, examId, examActivityId, identity, name, courseCode);
    }

    /**
     * 查询学生成绩信息(分页导出用)
     *
     * @param iPage
     * @param examId
     * @param examActivityId
     * @param identity
     * @param name
     * @param courseCode
     * @return
     */
    @Override
    public IPage<MarkResultSimpleExportDto> markResultQueryExportIpage(IPage<Map> iPage, Long examId, Long examActivityId, String identity, String name, String courseCode) {
        return teExamStudentMapper.markResultQueryExportIpage(iPage, examId, examActivityId, identity, name, courseCode);
    }

    @Override
    public List<TEExamStudentDto> findExamStudentNeedMark(Long examId, String courseCode, Long idGt, Integer count) {
        return teExamStudentMapper.findExamStudentNeedMark(examId, courseCode, idGt, count);
    }

    /**
     * 获取所有待阅卷的考生
     *
     * @param examId
     * @param examPaperIdSet
     * @param examStudentBreachPush
     * @return
     */
    @Override
    public List<TEExamStudent> findExamStudentNeedMarkAll(Long examId, Set<Long> examPaperIdSet, Boolean examStudentBreachPush) {
        return teExamStudentMapper.findExamStudentNeedMarkAll(examId, examPaperIdSet, examStudentBreachPush);
    }

    /**
     * 更新学生缓存
     *
     * @param examStudentId
     */
    @Override
    public void updateExamStudentByCache(Long examStudentId) {
        ExamStudentCacheBean examStudentCache = (ExamStudentCacheBean) redisUtil.get(RedisKeyHelper.examStudentCacheKey(examStudentId));
        if (Objects.nonNull(examStudentCache)) {
            TEExamStudent examStudent = GsonUtil.fromJson(GsonUtil.toJson(examStudentCache), TEExamStudent.class);
            this.saveOrUpdate(examStudent);
        }
    }

    /**
     * 获取考试次数为0的考生
     *
     * @param examId
     * @param examActivityId
     * @param id
     * @param examRecordId
     * @return
     */
    @Override
    public List<TEExamStudent> findAlreadyExamCountZero(Long examId, Long examActivityId, Long id, Long examRecordId) {
        return teExamStudentMapper.findAlreadyExamCountZero(examId, examActivityId, id, examRecordId);
    }

    /**
     * 获取缺考考生
     *
     * @param examId
     * @param examActivityId
     * @param roomCode
     * @return
     */
    @Override
    public Integer getAbsentCount(Long examId, Long examActivityId, String roomCode) {
        return this.baseMapper.getAbsentCount(examId, examActivityId, roomCode);
    }

    /**
     * 根据机构获取考试相关信息
     *
     * @param orgId
     * @return
     */
    @Override
    public List<ExamInfoBean> getExamInfo(Long orgId) {
        return this.baseMapper.getExamInfo(orgId);
    }
}
