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.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.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
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());
        }
        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.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 quService.saveOrUpdate(qu);
    }


    /**
     * 单个题库进行排序
     * @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 + "单选题不能包含多个正确项！");
        }
    }




}
