package com.zd.exam.service.impl;

import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.service.TokenService;
import com.zd.exam.domain.ElExam;
import com.zd.exam.domain.ElExamCertRelation;
import com.zd.exam.domain.ElExamQu;
import com.zd.exam.domain.ElExamRepo;
import com.zd.exam.domain.vo.ElExamVO;
import com.zd.exam.enums.ScopeType;
import com.zd.exam.mapper.ElExamCertRelationMapper;
import com.zd.exam.mapper.ElExamMapper;
import com.zd.exam.service.ElExamDeptService;
import com.zd.exam.service.ElExamRepoService;
import com.zd.exam.service.ElExamService;
import com.zd.exam.service.IElExamQuService;
import com.zd.system.api.model.LoginUser;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 课程(ElExam)表服务实现类
 *
 * @author liubo
 * @since 2021-08-31 09:09:15
 */
@Service("elExamService")
public class ElExamServiceImpl implements ElExamService {
    @Resource
    private ElExamMapper elExamMapper;
    @Autowired
    private ElExamRepoService elExamRepoService;
    @Autowired
    private IElExamQuService examQuService;
    @Autowired
    private ElExamDeptService elExamDeptService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ElExamCertRelationMapper examCertRelationMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ElExam queryById(Long id) {

        ElExam exam = elExamMapper.queryById(id);

        // 考试部门
        List<Long> departIds = elExamDeptService.queryByExamId(id);
        exam.setDeptIds(departIds);

        // 题库
        List<ElExamRepo> repos = elExamRepoService.queryByExamId(id);

        if(exam.getJoinType() == 2 && CollectionUtils.isNotEmpty(repos)){
            ElExamQu elExamQu = new ElExamQu();
            for (ElExamRepo repo : repos) {
                elExamQu.setExamRepoId(repo.getId());
                repo.setExamQuList(examQuService.selectElExamQuList(elExamQu));
            }
        }

        exam.setRepoList(repos);

        return exam;
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<ElExam> queryAllByLimit(int offset, int limit) {
        return this.elExamMapper.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param elExam 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public int insert(ElExam elExam) {

        // 校验 安全准入，负面清单，黑名单， 以组织架构为单位只能创建一个
        if(!Objects.equals(elExam.getScopeType(), ScopeType.SCOPE_4.getType())){
            checkOnlyOneExamByScopeType(elExam.getScopeType(), null, elExam.getDeptIds());
        }

        Date now = new Date();
        LoginUser loginUser = tokenService.getLoginUser();
        // 考试状态
        elExam.setState(1);
        // 计算分值
        this.calcScore(elExam);
        elExam.setCreateTime(now);
        elExam.setUserId(loginUser.getUserid());
        elExam.setCreateBy(loginUser.getUsername());
        elExam.setDeptId(loginUser.getSysUser().getDeptId());
        elExam.setDeptName(loginUser.getSysUser().getDeptName());
        int num = elExamMapper.insert(elExam);

        // 题库组卷
        updateExamRepo(elExam);

        return num;
    }

    /**
     * 校验 安全准入，负面清单，黑名单 类型的考试是否存在
     * @param scopeType 类型
     * @param examId 需要排除的考试
     * @param deptIds 组织架构 同一个组织架构该类型的考试只能创建一个
     */
    private void checkOnlyOneExamByScopeType(Integer scopeType, Long examId, List<Long> deptIds) {
        elExamDeptService.checkOnlyOneExamByScopeType(scopeType,examId,deptIds);
    }

    /**
     * 修改数据
     *
     * @param elExam 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public int update(ElExam elExam) {
        // 校验 安全准入，负面清单，黑名单， 以组织架构为单位只能创建一个
        if(!Objects.equals(elExam.getScopeType(), ScopeType.SCOPE_4.getType())){
            checkOnlyOneExamByScopeType(elExam.getScopeType(), elExam.getId(), elExam.getDeptIds());
        }

        // 计算分值
        this.calcScore(elExam);

        // 考试去掉绑定证书功能

        int num = elExamMapper.update(elExam);
        updateExamRepo(elExam);

        return num;
    }

    private void updateExamRepo(ElExam elExam) {
        elExamRepoService.saveAll(elExam);

        // 开放的部门
        if (2 == elExam.getOpenType()) {
            elExamDeptService.saveAll(elExam.getId(), elExam.getDeptIds());
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.elExamMapper.deleteById(id) > 0;
    }

    @Override
    @DataScope(deptAlias = "ed", userAlias = "e", permi = PerPrefix.EXAM_EXAM)
    public List<ElExam> queryList(ElExamVO examvo) {
        return elExamMapper.queryAll(examvo);
    }

    @Override
    @Transactional
    public int deleteByIds(List<Long> ids) {

        int num = elExamMapper.deleteByIds(ids);
        // 考试删除判断
        for (Long examId : ids) {
            // 删除考试关联
            elExamRepoService.deleteByExamId(examId);
            elExamDeptService.deleteByExamId(examId);
        }

        return num;
    }

    @Override
    @DataScope(deptAlias = "dept" , userAlias = "dept" , permi = PerPrefix.EXAM_EXAM)
    public List<ElExam> queryMyExamList(ElExam exam) {
        return elExamMapper.queryMyExamList(exam);
    }

    /**
     * 查询考试关联的试卷
     */
    @Override
    public List<ElExamCertRelation> queryCertById(ElExam exam) {
        return examCertRelationMapper.queryCertById(exam.getId());
    }

    /**
     * 保存考试关联的试卷
     */
    @Override
    @Transactional
    public void saveCertById(ElExam exam) {
        List<ElExamCertRelation> examCerts = exam.getExamCerts();
        if (CollectionUtils.isEmpty(examCerts)) {
            throw new ServiceException("证书不能为空");
        }
        if (examCerts.size() > 9) {
            throw new ServiceException("证书最多只能选9个！");
        }
        // 先删除
        examCertRelationMapper.deleteByExamId(exam.getId());
        for (ElExamCertRelation examCert : examCerts) {
            examCert.setExamId(exam.getId());
            examCert.setCreateTime(DateUtils.getNowDate());
        }
        examCertRelationMapper.insertBatch(examCerts);
    }

    @Override
    public void saveSafeTrainById(ElExam exam) {
        elExamMapper.update(exam);
    }


    /**
     * 计算分值
     *
     * @param exam
     */
    private void calcScore(ElExam exam) {

        // 主观题分数
        int objScore = 0;

        // 题库组卷
        if (1 == exam.getJoinType()) {
            List<ElExamRepo> repoList = exam.getRepoList();

            for (ElExamRepo item : repoList) {
                if (item.getRadioCount() != null
                        && item.getRadioCount() > 0
                        && item.getRadioScore() != null
                        && item.getRadioScore() > 0) {
                    objScore += item.getRadioCount() * item.getRadioScore();
                }
                if (item.getMultiCount() != null
                        && item.getMultiCount() > 0
                        && item.getMultiScore() != null
                        && item.getMultiScore() > 0) {
                    objScore += item.getMultiCount() * item.getMultiScore();
                }
                if (item.getJudgeCount() != null
                        && item.getJudgeCount() > 0
                        && item.getJudgeScore() != null
                        && item.getJudgeScore() > 0) {
                    objScore += item.getJudgeCount() * item.getJudgeScore();
                }
            }
        }

        exam.setTotalScore(objScore);
    }
}
