package com.ruoyi.web.controller.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.qu.ElQu;
import com.ruoyi.system.domain.qu.ElQuAnswer;
import com.ruoyi.system.domain.qu.ElQuRepo;
import com.ruoyi.system.domain.qu.dto.QuAnswerDTO;
import com.ruoyi.system.domain.qu.dto.export.QuExportDTO;
import com.ruoyi.system.domain.qu.dto.ext.QuDetailDTO;
import com.ruoyi.system.domain.qu.dto.request.QuQueryReqDTO;
import com.ruoyi.system.domain.qu.enums.QuType;
import com.ruoyi.system.service.ElQuAnswerService;
import com.ruoyi.system.service.ElQuRepoService;
import com.ruoyi.system.service.ElQuService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * packageName com.ruoyi.web.controller.manager
 *
 * @author wangxy
 * @version JDK 8
 * @className QuManager
 * @date 2024/6/27
 * @description
 */
@Component
public class QuManager {


    @Resource
    private ElQuService quService;


    @Resource
    private ElQuAnswerService quAnswerService;

    @Resource
    private ElQuRepoService quRepoService;


    /**
     * 查询
     *
     * @param qu
     * @return java.util.List<com.hyp.system.domain.SysNotice>
     */
    public List<ElQu> selectQuList(QuQueryReqDTO qu) {
        return quService.selectQuList(qu);
    }


    /**
     * 修改
     *
     * @param reqDTO
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(QuDetailDTO reqDTO) {
        // 校验数据
        this.checkData(reqDTO, "");
        ElQu qu = Convert.convert(ElQu.class, reqDTO);
        if (StringUtils.isNotEmpty(reqDTO.getId())) {
            qu.setUpdateTime(new Date());
            LambdaQueryWrapper<ElQuAnswer> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ElQuAnswer::getQuId,reqDTO.getId());
            quAnswerService.remove(wrapper);
            LambdaQueryWrapper<ElQuRepo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ElQuRepo::getQuId,reqDTO.getId());
            quRepoService.remove(queryWrapper);
        } else {
            qu.setCreateTime(new Date());
        }
        quService.saveOrUpdate(qu);
        if(CollUtil.isEmpty(reqDTO.getAnswerList())){
           throw new ServiceException("备选项列表不能为空");
        }
        if(CollUtil.isNotEmpty(reqDTO.getAnswerList())){
            List<ElQuAnswer> answerList = Convert.toList(ElQuAnswer.class, reqDTO.getAnswerList());
            answerList.forEach(elQuAnswer -> elQuAnswer.setQuId(qu.getId()));
            quAnswerService.saveBatch(answerList);
        }
        if(CollUtil.isEmpty(reqDTO.getRepoIds())){
            throw new ServiceException("题库列表不能为空");
        }
        if(CollUtil.isNotEmpty(reqDTO.getRepoIds())){
            List<ElQuRepo> list = new ArrayList<>();
            reqDTO.getRepoIds().forEach(repoId->{
                ElQuRepo ref = new ElQuRepo();
                ref.setQuId(qu.getId());
                ref.setRepoId(repoId);
                ref.setQuType(qu.getQuType());
                list.add(ref);
            });
            quRepoService.saveBatch(list);
            reqDTO.getRepoIds().forEach(this::sortRepo);
        }
        return true;
    }


    /**
     * 单个题库进行排序
     * @param repoId
     */
    private void sortRepo(String repoId){
        List<ElQuRepo> list = quRepoService.lambdaQuery()
                .eq(ElQuRepo::getRepoId, repoId).list();
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        int sort = 1;
        for(ElQuRepo item: list){
            item.setSort(sort);
            sort++;
        }
        quRepoService.saveOrUpdateBatch(list);
    }

    public QuDetailDTO detail(String id) {
        ElQu qu = quService.getById(id);
        QuDetailDTO detailDTO = Convert.convert(QuDetailDTO.class, qu);
        List<ElQuAnswer> quAnswers = quAnswerService.lambdaQuery().eq(ElQuAnswer::getQuId, id).list();
        List<QuAnswerDTO> list = Convert.toList(QuAnswerDTO.class, quAnswers);
        detailDTO.setAnswerList(list);
        List<ElQuRepo> repos = quRepoService.lambdaQuery()
                .eq(ElQuRepo::getQuId, id).list();
         List<String> repoIds = repos.stream().map(ElQuRepo::getRepoId).collect(Collectors.toList());
        detailDTO.setRepoIds(repoIds);
        return detailDTO;
    }


    @Transactional(rollbackFor = Exception.class)
    public boolean deleteQuByIds(String ids) {
        List<String> list = Arrays.asList(Convert.toStrArray(ids));
        quService.removeByIds(list);
        LambdaQueryWrapper<ElQuAnswer> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ElQuAnswer::getQuId,list);
        quAnswerService.remove(wrapper);
        LambdaQueryWrapper<ElQuRepo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ElQuRepo::getQuId,list);
        return quRepoService.remove(queryWrapper);
    }



    /**
     * 校验题目信息
     *
     * @param qu
     * @param no
     * @throws Exception
     */
    public void checkData(QuDetailDTO qu, String no) {
        if (StringUtils.isEmpty(qu.getContent())) {
            throw new ServiceException( no + "题目内容不能为空！");
        }
        if (CollectionUtils.isEmpty(qu.getRepoIds())) {
            throw new ServiceException(no + "至少要选择一个题库！");
        }
        List<QuAnswerDTO> answers = qu.getAnswerList();

        if (CollectionUtils.isEmpty(answers)) {
            throw new ServiceException( no + "客观题至少要包含一个备选答案！");
        }
        int trueCount = 0;
        for (QuAnswerDTO a : answers) {
            if (a.getIsRight() == null) {
                throw new ServiceException( no + "必须定义选项是否正确项！");
            }
            if (StringUtils.isEmpty(a.getContent())) {
                throw new ServiceException( no + "选项内容不为空！");
            }
            if (a.getIsRight()) {
                trueCount += 1;
            }
        }

        if (trueCount == 0) {
            throw new ServiceException(no + "至少要包含一个正确项！");
        }
        //单选题
        if (qu.getQuType().equals(QuType.RADIO) && trueCount > 1) {
            throw new ServiceException( no + "单选题不能包含多个正确项！");
        }
    }


    public int importExcel(List<QuExportDTO> dtoList) {
        // 校验数据
        checkExcel(dtoList);
        //根据题目名称分组
        Map<Integer, List<QuExportDTO>> anMap = new HashMap<>(16);
        //题目本体信息
        Map<Integer, QuExportDTO> quMap = new HashMap<>(16);
        //数据分组
        for (QuExportDTO item : dtoList) {
            // 空白的ID
            if (StringUtils.isEmpty(item.getNo())) {
                continue;
            }
            Integer key;
            //序号
            try {
                key = Integer.parseInt(item.getNo());
            } catch (Exception e) {
                continue;
            }
            //如果已经有题目了，直接处理选项
            if (anMap.containsKey(key)) {
                anMap.get(key).add(item);
            } else {
                //如果没有，将题目内容和选项一起
                List<QuExportDTO> subList = new ArrayList<>();
                subList.add(item);
                anMap.put(key, subList);
                quMap.put(key, item);
            }
        }
        int count = 0;
        try {
            //循环题目插入
            for (Integer key : quMap.keySet()) {
                QuExportDTO im = quMap.get(key);
                //题目基本信息
                QuDetailDTO qu = new QuDetailDTO();
                qu.setContent(im.getQContent());
                qu.setAnalysis(im.getQAnalysis());
                qu.setQuType(Integer.parseInt(im.getQuType()));
                qu.setCreateTime(new Date());

                //设置回答列表
                List<QuAnswerDTO> answerList = this.processAnswerList(anMap.get(key));
                //设置题目
                qu.setAnswerList(answerList);
                //设置引用题库
                qu.setRepoIds(im.getRepoList());
                // 保存答案
                this.saveOrUpdate(qu);
                count++;
            }
        } catch (ServiceException e) {
            throw new ServiceException("导入出现问题，行：" + count + "，" + e.getMessage());
        }
        return count;
    }

    /**
     * 处理回答列表
     *
     * @param importList
     * @return
     */
    private List<QuAnswerDTO> processAnswerList(List<QuExportDTO> importList) {

        List<QuAnswerDTO> list = new ArrayList<>(16);
        for (QuExportDTO item : importList) {
            QuAnswerDTO a = new QuAnswerDTO();
            a.setIsRight("1".equals(item.getAIsRight()));
            a.setContent(item.getAContent());
            a.setAnalysis(item.getAAnalysis());
            a.setId("");
            list.add(a);
        }
        return list;
    }

    /**
     * 校验Excel
     *
     * @param list
     * @throws Exception
     */
    private void checkExcel(List<QuExportDTO> list) throws ServiceException {
        // 约定第三行开始导入
        int line = 3;
        StringBuffer sb = new StringBuffer();
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException( "您导入的数据似乎是一个空表格！");
        }
        Integer quNo = null;
        for (QuExportDTO item : list) {
            if (org.apache.commons.lang3.StringUtils.isBlank(item.getNo())) {
                line++;
                continue;
            }
            Integer no;
            try {
                no = Integer.parseInt(item.getNo());
            } catch (Exception e) {
                line++;
                continue;
            }
            if (no == null) {
                sb.append("第" + line + "行，题目序号不能为空！<br>");
            }
            if (quNo == null || !quNo.equals(no)) {
                if (item.getQuType() == null) {
                    sb.append("第" + line + "行，题目类型不能为空<br>");
                }
                if (StringUtils.isBlank(item.getQContent())) {
                    sb.append("第" + line + "行，题目内容不能为空<br>");
                }
                if (CollectionUtils.isEmpty(item.getRepoList())) {
                    sb.append("第" + line + "行，题目必须包含一个题库<br>");
                }
            }
            if (org.apache.commons.lang3.StringUtils.isBlank(item.getAIsRight())) {
                sb.append("第" + line + "行，选项是否正确不能为空<br>");
            }
            if (org.apache.commons.lang3.StringUtils.isBlank(item.getAContent()) && org.apache.commons.lang3.StringUtils.isBlank(item.getAImage())) {
                sb.append("第" + line + "行，选项内容和选项图片必须有一个不为空<br>");
            }
            quNo = no;
            line++;
        }
        // 存在错误
        if (!"".equals(sb.toString())) {
            throw new ServiceException(sb.toString());
        }
    }





}
