package jnpf.cultivate.v2.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jnpf.base.service.SuperServiceImpl;
import jnpf.cultivate.mapper.FtbCultivateQuestionMapper;
import jnpf.cultivate.service.FtbCultivateQuestionOptionService;
import jnpf.cultivate.v2.service.V2CultivateQuestionService;
import jnpf.cultivate.v2.util.V2QuestionExcelExportUtil;
import jnpf.model.cultivate.po.question.FtbCultivateQuestion;
import jnpf.model.cultivate.po.question.FtbCultivateQuestionOption;
import jnpf.model.cultivate.req.questionbank.QuestionOptionReq;
import jnpf.model.cultivate.resp.QuestionOptionVo;
import jnpf.model.cultivate.resp.QuestionVo;
import jnpf.model.cultivate.v2.question.req.*;
import jnpf.model.enums.CourseEnums;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class V2CultivateQuestionServiceImpl extends SuperServiceImpl<FtbCultivateQuestionMapper, FtbCultivateQuestion> implements V2CultivateQuestionService {

    /**
     * 题目选项服务
     */
    @Autowired
    private FtbCultivateQuestionOptionService questionOptionService;

    @Override
    @Transactional
    public void batchAddQuestion(BatchAddQuestionReq batchAddQuestionReq) throws Exception {
        preCheckParam(batchAddQuestionReq);
        String questionBankId = batchAddQuestionReq.getQuestionBankId();
        List<FtbCultivateQuestion> questionList = new ArrayList<>();
        List<FtbCultivateQuestionOption> questionOptionList = new ArrayList<>();

        LambdaQueryWrapper<FtbCultivateQuestion> wrapper = new LambdaQueryWrapper<FtbCultivateQuestion>()
                .select(FtbCultivateQuestion::getContent)
                .eq(FtbCultivateQuestion::getEnabledMark, CourseEnums.EnabledMarkType.VALID.getCode());
        List<FtbCultivateQuestion> existQuestionList = baseMapper.selectList(wrapper);

        List<String> questionContentList = new ArrayList<>();
        if(CollUtil.isNotEmpty(existQuestionList)) {
            for (FtbCultivateQuestion question : existQuestionList) {
                questionContentList.add(question.getContent());
            }
        }
        //检查题目是否重复
        for (V2AddQuestionReq req : batchAddQuestionReq.getQuestionList()) {
            if(questionContentList.contains(req.getContent())){
                throw new RuntimeException("题目已经存在");
            }
            //1、添加题目信息
            FtbCultivateQuestion question = req.convertData(questionBankId);
            questionList.add(question);
            // ftbCultivateQuestionMapper.insert(question);
            //2、添加题目选项信息
            if (CourseEnums.QuestionType.INPUT.getCode().equals(question.getType()) || CourseEnums.QuestionType.COMBINE.getCode().equals(question.getType())) {
                continue;
            }
            List<QuestionOptionReq> optionList = req.getOptionList();
            if (CollUtil.isEmpty(optionList)) {
                continue;
            }
            for (QuestionOptionReq option : optionList) {
                questionOptionList.add(option.convertData(question.getId()));
            }
            // questionOptionService.saveBatch(questionOptionList);
            log.info(questionOptionList.toString());
            //3、写入正确答案
            FtbCultivateQuestion questionHasAnswer = writeRightAnswer(question, questionOptionList);
            question.setAnswer(questionHasAnswer.getAnswer());

        }
        if (questionList.isEmpty()) {
            return;
        }
        this.saveBatch(questionList);
        if (!questionOptionList.isEmpty()) {
            questionOptionService.saveBatch(questionOptionList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateData(V2EditQuestionReq req) throws Exception {
        //1、检测题目信息
        FtbCultivateQuestion question = this.baseMapper.selectById(req.getId());
        if (null == question) {
            throw new RuntimeException("题目不存在");
        }
        if (question.getEnabledMark().equals(CourseEnums.EnabledMarkType.INVALID.getCode())) {
            throw new RuntimeException("题目已经被删除，不能操作");
        }
        //1、修改题目信息
        question.setType(req.getType());
        question.setDifficulty(req.getDifficulty());
        question.setContent(req.getContent());
        question.setAnalysis(req.getAnalysis());
        question.setAnswer(req.getAnswer());
        questionOptionService.remove(new QueryWrapper<FtbCultivateQuestionOption>().eq("F_QuestionId", question.getId()));
        //2、添加题目选项信息
        if (!CourseEnums.QuestionType.INPUT.getCode().equals(question.getType()) && !CourseEnums.QuestionType.COMBINE.getCode().equals(question.getType())) {
            List<QuestionOptionReq> optionList = req.getOptionList();
            if (CollUtil.isNotEmpty(optionList)) {
                List<FtbCultivateQuestionOption> questionOptionList = new ArrayList<>();
                for (QuestionOptionReq option : optionList) {
                    questionOptionList.add(option.convertData(question.getId()));
                }
                questionOptionService.saveBatch(questionOptionList);
                //3、写入正确答案
                FtbCultivateQuestion questionHasAnswer = writeRightAnswer(question, questionOptionList);
                question.setAnswer(questionHasAnswer.getAnswer());
            }
        }
        this.baseMapper.updateById(question);
    }

    @Override
    public QuestionVo getInfo(String id) {
        //1、检测题目信息
        FtbCultivateQuestion question = this.baseMapper.selectById(id);
        if (null == question) {
            throw new RuntimeException("题目不存在");
        }
        if (question.getEnabledMark().equals(CourseEnums.EnabledMarkType.INVALID.getCode())) {
            throw new RuntimeException("题目已经被删除，不能操作");
        }
        //2、题目po转vo
        QuestionVo vo = BeanUtil.copyProperties(question, QuestionVo.class);
        //3、查询题目的选项信息
        if (!CourseEnums.QuestionType.INPUT.getCode().equals(question.getType())
                && !CourseEnums.QuestionType.COMBINE.getCode().equals(question.getType())) {
            List<FtbCultivateQuestionOption> questionOptionList = queryOptionListForQuestionId(id);
            if (CollUtil.isNotEmpty(questionOptionList)) {
                vo.setQuestionOptionVoList(BeanUtil.copyToList(questionOptionList, QuestionOptionVo.class));
            }
        }
        return vo;
    }

    @Override
    public V2ImportQuestionResultVo realImportData(String questionBankId, List<V2ExcelImportQuestionResultReq> allQuestionList) {
        List<V2AddQuestionReq> failList = new ArrayList<>();
        List<V2AddQuestionReq> successList = new ArrayList<>();
        allQuestionList.forEach(req -> {
            V2AddQuestionReq addQuestionReq = BeanUtil.copyProperties(req, V2AddQuestionReq.class);
            try {
                insertData(questionBankId, addQuestionReq);
                successList.add(addQuestionReq);
            } catch (Exception e) {
                log.error("导入题目失败", e);
                failList.add(addQuestionReq);
            }
        });
        return V2ImportQuestionResultVo.builder().successList(successList).failList(failList).build();
    }

    public void insertData(String questionBankId, V2AddQuestionReq req) throws Exception {
        //1、添加题目信息
        FtbCultivateQuestion question = req.convertData(questionBankId);
        this.baseMapper.insert(question);
        //2、添加题目选项信息
        if (CourseEnums.QuestionType.INPUT.getCode().equals(question.getType()) || CourseEnums.QuestionType.COMBINE.getCode().equals(question.getType())) {
            return;
        }
        List<QuestionOptionReq> optionList = req.getOptionList();
        if (CollUtil.isEmpty(optionList)) {
            return;
        }
        List<FtbCultivateQuestionOption> questionOptionList = new ArrayList<>();
        for (QuestionOptionReq option : optionList) {
            questionOptionList.add(option.convertData(question.getId()));
        }
        questionOptionService.saveBatch(questionOptionList);
        log.info(questionOptionList.toString());
        //3、写入正确答案
        FtbCultivateQuestion questionHasAnswer = writeRightAnswer(question, questionOptionList);
        question.setAnswer(questionHasAnswer.getAnswer());
        this.baseMapper.updateById(question);
    }


    /**
     * 根据题目ID查 题目选项列表
     *
     * @param questionId 题目ID
     */
    private List<FtbCultivateQuestionOption> queryOptionListForQuestionId(String questionId) {
        QueryWrapper<FtbCultivateQuestionOption> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbCultivateQuestionOption::getQuestionId, questionId)
                .eq(FtbCultivateQuestionOption::getEnabledMark, CourseEnums.EnabledMarkType.VALID.getCode())
                .orderByAsc(FtbCultivateQuestionOption::getSortCode);
        return questionOptionService.list(wrapper);
    }

    /**
     * 写入正确答案
     *
     * @param question           题目信息
     * @param questionOptionList 题目选项信息
     */
    private FtbCultivateQuestion writeRightAnswer(FtbCultivateQuestion question, List<FtbCultivateQuestionOption> questionOptionList) throws Exception {
        List<String> rightAnswerList = new ArrayList<>();
        if (CourseEnums.QuestionType.SINGLE.getCode().equals(question.getType())
                || CourseEnums.QuestionType.MULTI.getCode().equals(question.getType())
                || CourseEnums.QuestionType.JUDGE.getCode().equals(question.getType())
                || CourseEnums.QuestionType.ONE_OR_MULTI.getCode().equals(question.getType())
        ) {
            for (FtbCultivateQuestionOption questionOption : questionOptionList) {
                if (CourseEnums.IsRightAnswer.YES.getCode().equals(questionOption.getIsRightOption())) {
                    rightAnswerList.add(questionOption.getId());
                }
            }
        }
        if (CourseEnums.QuestionType.FILL.getCode().equals(question.getType())) {
            for (FtbCultivateQuestionOption questionOption : questionOptionList) {
                rightAnswerList.add(questionOption.getId());
            }
        }
        if (rightAnswerList.isEmpty()) {
            throw new Exception("请设置正确答案");
        }
        FtbCultivateQuestion updateQuestion = new FtbCultivateQuestion();
        updateQuestion.setAnswer(String.join(",", rightAnswerList));
        updateQuestion.setId(question.getId());
        // ftbCultivateQuestionMapper.updateById(updateQuestion);
        return updateQuestion;
    }

    private void preCheckParam(BatchAddQuestionReq req) {
        if (req.getQuestionBankId() == null) {
            throw new RuntimeException("题库ID不能为空");
        }
        if (CollUtil.isEmpty(req.getQuestionList())) {
            throw new RuntimeException("题目列表不能为空");
        }
        for (V2AddQuestionReq question : req.getQuestionList()) {
            V2QuestionExcelExportUtil.checkAddQuestionParam(question);
        }
    }
}