package com.testor.module.train.paper.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.testor.biz.rule.service.SysRuleService;
import com.testor.biz.sys.dict.data.controller.SysDictDataController;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.common.constant.DefaultRule;
import com.testor.module.train.exam.model.domain.TTrainExamChoice;
import com.testor.module.train.exam.model.domain.TTrainExamJudgment;
import com.testor.module.train.exam.model.domain.TTrainQuestionBank;
import com.testor.module.train.exam.model.domain.TTrainTestQuestions;
import com.testor.module.train.exam.model.dto.TTrainTestQuestionsParam;
import com.testor.module.train.exam.service.TTrainExamChoiceService;
import com.testor.module.train.exam.service.TTrainExamJudgmentService;
import com.testor.module.train.exam.service.TTrainQuestionBankService;
import com.testor.module.train.exam.service.TTrainTestQuestionsService;
import com.testor.module.train.paper.dao.TTrainPaperDao;
import com.testor.module.train.paper.model.domain.TTrainPaper;
import com.testor.module.train.paper.model.dto.*;
import com.testor.module.train.paper.service.TTrainPaperService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.TypeHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 试卷管理——安全教育培训Service业务层处理
 *
 * @author testor-framework
 * @date 2022-07-13 15:25:11
 */
@Service
public class TTrainPaperServiceImpl extends SuperServiceImpl<TTrainPaperDao, TTrainPaper> implements TTrainPaperService {
    @Autowired(required = false)
    private TTrainPaperDao tTrainPaperDao;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private TTrainQuestionBankService tTrainQuestionBankService;
    @Autowired
    private SysRuleService sysRuleService;
    @Autowired
    private TTrainTestQuestionsService tTrainTestQuestionsService;
    @Autowired
    private TTrainExamChoiceService tTrainExamChoiceService;
    @Autowired
    private TTrainExamJudgmentService tTrainExamJudgmentService;

    @Override
    public BaseResponse<List<TTrainQuestionBank>> getQuestionBank() throws Exception {
        QueryWrapper<TTrainQuestionBank> queryWrapper = new QueryWrapper<>();
        String rule = sysRuleService.dataRuleScope(DefaultRule.DEPT_ALL.name());
        if (StringUtils.isNotEmpty(rule)) {
            queryWrapper.apply(rule);
        }
        queryWrapper.ne(TTrainQuestionBank.STATUS, "1")
                .ne(TTrainQuestionBank.QUESTION_BANK_STATUS, "0");
        List<TTrainQuestionBank> list = tTrainQuestionBankService.list(queryWrapper);
        BaseResponse<List<TTrainQuestionBank>> baseResponse = new BaseResponse<>();
        baseResponse.setData(list);
        return baseResponse;
    }

    @Override
    public BaseResponse<TTrainPaper> addEntity(TTrainPaper addRequest) throws Exception {
        if (ObjectHelper.isEmpty(addRequest)) {
            throw new BusinessException("请求参数有误");
        }
        UserInfo loginUser = ContextUtils.getLoginUser();
        SysOrg sysOrg = sysOrgService.getById(loginUser.getOrgId());
        if (Objects.isNull(sysOrg)) {
            throw new BusinessException("当前登录人部门信息不存在，请联系管理员！");
        }
        BaseResponse<TTrainPaper> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(addRequest)) {
            String id = addRequest.getId();
            if (ObjectHelper.isEmpty(id)) {
                id = IdHelper.getId32bit();
            }
            TTrainPaper data = BeanHelper.beanToBean(addRequest, TTrainPaper.class);
            data.setOrgId(loginUser.getOrgId());
            data.setOrgName(sysOrg.getOrgName());
            if (ObjectHelper.isEmpty(addRequest.getId())) {
                data.setTestPaperStatus("1");
            }
            data.setId(id);
//            org.springframework.dao.DataIntegrityViolationException
            boolean result = false;
            try {
                result = this.saveOrUpdate(data);
            } catch (org.springframework.dao.DataIntegrityViolationException e) {
                throw new BusinessException("试卷名称太长");
            }
            if (result) {
                TTrainPaper newEntity = new TTrainPaper();
                newEntity.setId(id);
                baseResponse.setData(newEntity);
            }
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<ReturnTrainPaper> detail(String id) throws Exception {
        BaseResponse<ReturnTrainPaper> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(id)) {
            TTrainPaper data = this.getById(id);
            String testQuestionsId = data.getTestQuestionsId();
            // 多个试题id
            List<String> list = Arrays.asList(testQuestionsId.split(","));
            QueryWrapper<TTrainTestQuestions> queryWrapper = new QueryWrapper<>();
            queryWrapper.in(TTrainTestQuestions.ID, list);
            //试卷包含的所有试题
            List<TTrainTestQuestions> trainTestQuestionsList = tTrainTestQuestionsService.list(queryWrapper);
            // 返回试卷详情
            ReturnTrainPaper returnTrainPaper = new ReturnTrainPaper();
            // 存储所有的题目
            List<TestQuestionsContent> testQuestionsContents = new ArrayList<>();
            for (TTrainTestQuestions tTrainTestQuestions : trainTestQuestionsList) {
                // 试题解析
                String testQuestionsAnalysis = tTrainTestQuestions.getTestQuestionsAnalysis();
                String testQuestionsType = tTrainTestQuestions.getTestQuestionsType();
                //试题id
                String questionsId = tTrainTestQuestions.getId();
                if ("SELECT".equals(testQuestionsType) || "MORE_SELECT".equals(testQuestionsType)) {
                    // 每一个题目
                    TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                    QueryWrapper<TTrainExamChoice> wrapper = new QueryWrapper<>();
                    wrapper.eq(TTrainExamChoice.TEST_QUESTIONS_ID, questionsId);
                    // 当前题目包含的所有选项
                    List<TTrainExamChoice> list1 = tTrainExamChoiceService.list(wrapper);
                    // 按照选项排序
                    list1 = list1.stream().sorted(Comparator.comparing(TTrainExamChoice::getOptions))
                            .collect(Collectors.toList());
                    List<Options> optionsList = new ArrayList<>();
                    for (TTrainExamChoice tTrainExamChoice : list1) {
                        Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                        String optionsTest = options.getOptions() + ": " + options.getOptionText();
                        options.setOptionText(optionsTest);
                        optionsList.add(options);
                    }
                    String testQuestionsContent1 = testQuestionsContent.getTestQuestionsContent();
                    testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                    testQuestionsContent.setOptions(optionsList);
                    String score = "";
                    if ("SELECT".equals(testQuestionsType)) {
                        score = "(单选题、" + data.getSingleScore() + "分)";
                    }
                    if ("MORE_SELECT".equals(testQuestionsType)) {
                        score = "(多选题、" + data.getMoreScore() + "分)";
                    }
                    testQuestionsContent.setScore(score);
                    testQuestionsContent.setDictKey(testQuestionsType);
                    testQuestionsContent.setTestQuestionsAnalysis(testQuestionsAnalysis);
                    testQuestionsContents.add(testQuestionsContent);
                }
                if ("JUDGE".equals(testQuestionsType)) {
                    // 每一个题目
                    TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                    QueryWrapper<TTrainExamJudgment> wrapper = new QueryWrapper<>();
                    wrapper.eq(TTrainExamJudgment.TEST_QUESTIONS_ID, questionsId);
                    // 当前题目包含的所有选项
                    List<TTrainExamJudgment> list1 = tTrainExamJudgmentService.list(wrapper);
                    // 按照选项排序
                    list1 = list1.stream().sorted(Comparator.comparing(TTrainExamJudgment::getOptions))
                            .collect(Collectors.toList());
                    List<Options> optionsList = new ArrayList<>();
                    for (TTrainExamJudgment tTrainExamChoice : list1) {
                        Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                        String optionsTest = options.getOptions() + ": " + options.getOptionText();
                        options.setOptionText(optionsTest);
                        optionsList.add(options);
                    }
                    String testQuestionsContent1 = testQuestionsContent.getTestQuestionsContent();
                    testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                    testQuestionsContent.setOptions(optionsList);
                    String score = "";
                    if ("JUDGE".equals(testQuestionsType)) {
                        score = "(判断题、" + data.getJudgeScore() + "分)";
                    }
                    testQuestionsContent.setScore(score);
                    testQuestionsContent.setDictKey(testQuestionsType);
                    testQuestionsContent.setTestQuestionsAnalysis(testQuestionsAnalysis);
                    testQuestionsContents.add(testQuestionsContent);
                }
                List<TestQuestionsContent> collect = testQuestionsContents.stream()
                        .sorted(Comparator.comparing(TestQuestionsContent::getDictKey).reversed()).collect(Collectors.toList());
                returnTrainPaper.setTestQuestionsContent(collect);
            }
            List<TestQuestionsContent> testQuestionsContent = returnTrainPaper.getTestQuestionsContent();
            if (!CollectionUtils.isEmpty(testQuestionsContent)&& testQuestionsContent.size()>0) {
                AtomicInteger num = new AtomicInteger(1);
                testQuestionsContent.stream().forEach(item->{
                    item.setTestQuestionsContent(num.getAndIncrement() +"."+item.getTestQuestionsContent());
                });
            }

            returnTrainPaper.setTestQuestionsContent(null);
            returnTrainPaper.setTestQuestionsContent(testQuestionsContent);
            returnTrainPaper.setFullScore(data.getFullScore());
            returnTrainPaper.setPassScore(data.getPassScore());
            returnTrainPaper.setTestPaperName(data.getTestPaperName());
            baseResponse.setData(returnTrainPaper);
        } else {
            throw new BusinessException("请求参数不正确");
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<TTrainPaperParam> getByIds(String id) throws Exception {
        BaseResponse<TTrainPaperParam> baseResponse = new BaseResponse<>();
        if (StringHelper.isNotEmpty(id)) {
            TTrainPaper data = this.getById(id);
            TTrainPaperParam tTrainPaperParam = BeanHelper.beanToBean(data, TTrainPaperParam.class);
            String testQuestionsId = data.getTestQuestionsId();
            String[] split = testQuestionsId.split(",");
            List<TTrainTestQuestions> list = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                    .in(TTrainTestQuestions.ID, split)
                    .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
            );
            List<TTrainTestQuestionsParam> questionsList = null;
            if (ObjectHelper.isNotEmpty(list)) {
                 questionsList = converDict(list);
            }
            tTrainPaperParam.setTTrainTestQuestions(questionsList);
            baseResponse.setData(tTrainPaperParam);
        } else {
            throw new BusinessException("请求参数为不正确");
        }
        return baseResponse;
    }

    @Autowired
    private SysDictDataController sysDictDataController;

    private List<TTrainTestQuestionsParam> converDict(List<TTrainTestQuestions> baseResponseList) {
        List<TTrainTestQuestionsParam> data1 = new ArrayList<>();
        for (TTrainTestQuestions datum : baseResponseList) {
            TTrainTestQuestionsParam tTrainDatabase = BeanHelper.beanToBean(datum, TTrainTestQuestionsParam.class);
            String stairSubject = tTrainDatabase.getTestQuestionsType();
            tTrainDatabase.setDicKey(stairSubject);
            String subject_level = sysDictDataController.getDictTypeDetail("", "TEST_QUESTIONS_TYPE", stairSubject).getData().getDictValue();
            tTrainDatabase.setTestQuestionsType(subject_level);
            data1.add(tTrainDatabase);
        }

        return data1;
    }

    @Override
    public BaseResponse<BizGeneralResponse> updateEntity(TTrainPaper updateRequest) throws Exception {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(updateRequest) && StringHelper.isNotEmpty(updateRequest.getId())) {
            TTrainPaper data = BeanHelper.beanToBean(updateRequest, TTrainPaper.class);
            boolean result = this.updateById(data);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        } else {
            throw new BusinessException("请求参数为不正确");
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<BizGeneralResponse> deleteEntity(TTrainPaperDelParam deleteRequest) throws Exception {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(deleteRequest) && StringHelper.isNotEmpty(deleteRequest.getId())) {
            TTrainPaper data = new TTrainPaper();
            data.setId(deleteRequest.getId());
            data.setStatus(BizConstants.STATUS_DELETE);
            boolean result = this.updateById(data);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        } else {
            throw new BusinessException("请求参数为不正确");
        }
        return baseResponse;
    }

    @Override
    public String getTestPaperName(String testPaperId) {
        TTrainPaper trainPaper = getById(testPaperId);
        if (ObjectHelper.isEmpty(trainPaper)) {
            return "";
        }
        return trainPaper.getTestPaperName();
    }

    @Override
    public List<TTrainPaper> selectByExaminationManageId(String examinationManageId) {
        return baseMapper.selectByExaminationManageId(examinationManageId);
    }
}
