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.datascope.annotation.DataScope;
import com.zd.common.security.service.TokenService;
import com.zd.exam.domain.ElQu;
import com.zd.exam.domain.ElQuAnswer;
import com.zd.exam.mapper.ElQuAnswerMapper;
import com.zd.exam.mapper.ElQuMapper;
import com.zd.exam.mapper.ElQuRepoMapper;
import com.zd.exam.service.ElQuAnswerService;
import com.zd.exam.service.ElQuRepoService;
import com.zd.exam.service.ElQuService;
import com.zd.system.api.domain.SysUser;
import com.zd.system.api.model.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * 问题题目(ElQu)表服务实现类
 *
 * @author liubo
 * @since 2021-08-30 15:26:29
 */
@Service("elQuService")
public class ElQuServiceImpl implements ElQuService {
    @Resource
    private ElQuMapper elQuMapper;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ElQuAnswerService elQuAnswerService;
    @Resource
    private ElQuAnswerMapper elQuAnswerMapper;
    @Autowired
    private ElQuRepoService elQuRepoService;
    @Resource
    private ElQuRepoMapper elQuRepoMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ElQu queryById(Long id) {
        ElQu qu = this.elQuMapper.queryById(id);
        if (qu == null) {
            throw new ServiceException("未查询到数据，ID 无效！");
        }
        List<ElQuAnswer> answerList = elQuAnswerService.queryByQuId(id);
        qu.setAnswerList(answerList);

//        List<Long> repoIds = elQuRepoService.queryByQuId(id);
//        qu.setRepoIds(repoIds);
        return qu;
    }

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

    /**
     * 新增数据
     *
     * @param elQu 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public int insert(ElQu elQu) {
        // 校验数据
        this.checkData(elQu, "");

        SysUser user = tokenService.getLoginUser().getSysUser();

        if(user.getDept() != null){
            elQu.setDeptId(user.getDeptId());
            elQu.setDeptName(user.getDept().getDeptName());
        }

        elQu.setUserId(user.getUserId());
        elQu.setCreateBy(user.getUserName());
        elQu.setCreateTime(new Date());
        int num = elQuMapper.insert(elQu);

        // 保存全部问题
        elQuAnswerService.saveAll(elQu.getId(), elQu.getAnswerList());

        // 保存关联题库
        //elQuRepoService.saveAll(elQu.getId(), elQu.getQuType(), elQu.getRepoIds());

        return num;
    }

    /**
     * 修改数据
     *
     * @param elQu 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public int update(ElQu elQu) {
        // 校验数据
        this.checkData(elQu, "");

        LoginUser loginUser = tokenService.getLoginUser();

        elQu.setUserId(loginUser.getUserid());
        elQu.setUpdateBy(loginUser.getSysUser().getUserName());
        elQu.setUpdateTime(new Date());
        int num = elQuMapper.update(elQu);

        // 保存全部问题
        elQuAnswerService.saveAll(elQu.getId(), elQu.getAnswerList());

        // 保存关联题库
        //elQuRepoService.saveAll(elQu.getId(), elQu.getQuType(), elQu.getRepoIds());
        return num;
    }

    /**
     * 校验题目信息
     *
     * @param qu
     * @param no
     * @throws Exception
     */
    public void checkData(ElQu qu, String no) {
        if (StringUtils.isEmpty(qu.getContent())) {
            throw new ServiceException(no + "题目内容不能为空！");
        }

        /*if (CollectionUtils.isEmpty(qu.getRepoIds())) {
            throw new ServiceException(no + "至少要选择一个题库！");
        }*/

        List<ElQuAnswer> answers = qu.getAnswerList();

        if (CollectionUtils.isEmpty(answers)) {
            throw new ServiceException(no + "客观题至少要包含一个备选答案！");
        }

        int trueCount = 0;
        for (ElQuAnswer a : answers) {
            if (a.getIsRight() == null) {
                throw new ServiceException(no + "必须定义选项是否正确项！");
            }

            if (StringUtils.isEmpty(a.getContent())) {
                throw new ServiceException(no + "选项内容不为空！");
            }

            if (a.getIsRight() != null && a.getIsRight() == 1) {
                trueCount += 1;
            }
        }

        if (trueCount == 0) {
            throw new ServiceException(no + "至少要包含一个正确项！");
        }

        //单选题 1 单选题 2 多选题 3 判断题
        if (qu.getQuType().equals(1) && trueCount > 1) {
            throw new ServiceException(no + "单选题不能包含多个正确项！");
        }

    }

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

    @Override
    public int deleteByIds(List<Long> ids) {
        int num = elQuMapper.deleteByIds(ids);
        if (num > 0) {
            for (Long id : ids) {
                elQuAnswerMapper.deleteByQuId(id);

                elQuRepoMapper.deleteByQuId(id);
            }
        }
        return num;
    }

    @Override
    @DataScope(deptAlias = "q",userAlias = "q", permi = PerPrefix.EXAM_QU)
    public List<ElQu> queryList(ElQu qu) {
        List<ElQu> quList = elQuMapper.queryAll(qu);

        /*for (ElQu elQu : quList) {
            elQu.setRepoIds(elQuRepoService.queryByQuId(elQu.getId()));
        }*/
        return quList;
    }

    @Override
    public List<ElQu> selectElQuList(ElQu elQu) {
        return elQuMapper.queryAll(elQu);
    }

    @Override
    public String importData(List<ElQu> quList) {
        elQuMapper.insertBatch(quList);
        return "导入成功";
    }

    @Override
    public List<ElQu> listByRandom(Long classifyId, Integer quType, Integer level, List<Long> excludes, Integer size) {
        return elQuMapper.listByRandomClassifyId(classifyId, quType, level, excludes, size);
    }

    @Override
    public List<ElQu> otherListByRandom(Long repoId, Integer quType, Integer level, List<Long> excludes, Integer size) {
        return elQuMapper.otherListByRandom(repoId, quType, level, excludes, size);
    }

    @Override
    public List<ElQu> queryByIds(List<Long> quIds) {
        return elQuMapper.queryByIds(quIds, null, null);
    }

    @Override
    public Map<String, Integer> selectQuCountByClassifyIds(List<Long> classifyIds) {
        return elQuMapper.selectQuCountByClassifyIds(classifyIds);
    }
}
