package com.hotwj.platform.config.examPaper.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotwj.platform.config.examPaper.domain.HotExamPaper;
import com.hotwj.platform.config.examPaper.domain.bo.ExamPaperSaveQuestionsBo;
import com.hotwj.platform.config.examPaper.domain.bo.HotExamPaperBo;
import com.hotwj.platform.config.examPaper.domain.vo.ExamPaperSaveQuestionsResultVo;
import com.hotwj.platform.config.examPaper.domain.vo.HotExamPaperVo;
import com.hotwj.platform.config.examPaper.mapper.HotExamPaperMapper;
import com.hotwj.platform.config.examPaper.service.IHotExamPaperService;
import com.hotwj.platform.config.examPaperQuestion.domain.HotExamPaperQuestion;
import com.hotwj.platform.config.examPaperQuestion.mapper.HotExamPaperQuestionMapper;
import com.hotwj.platform.config.questionBank.domain.HotQuestionBank;
import com.hotwj.platform.config.questionBank.mapper.HotQuestionBankMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 试卷库Service业务层处理
 *
 * @author shihongwei
 * @date 2025-12-23
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class HotExamPaperServiceImpl implements IHotExamPaperService {

    private final HotExamPaperMapper baseMapper;
    private final HotExamPaperQuestionMapper examPaperQuestionMapper;
    private final HotQuestionBankMapper questionBankMapper;

    /**
     * 查询试卷库
     *
     * @param id 主键
     * @return 试卷库
     */
    @Override
    public HotExamPaperVo queryById(Long id) {
        HotExamPaperVo vo = baseMapper.selectVoById(id);
        if (vo == null || vo.getId() == null) {
            return vo;
        }

        List<HotExamPaperQuestion> relations = examPaperQuestionMapper.selectList(
                Wrappers.<HotExamPaperQuestion>lambdaQuery()
                        .eq(HotExamPaperQuestion::getPaperId, vo.getId())
        );
        if (relations == null || relations.isEmpty()) {
            vo.setSingleChoiceCount(0L);
            vo.setMultiChoiceCount(0L);
            vo.setJudgeCount(0L);
            vo.setSingleChoiceScore(0L);
            vo.setMultiChoiceScore(0L);
            vo.setJudgeScore(0L);
            return vo;
        }

        long singleCount = 0L;
        long multiCount = 0L;
        long judgeCount = 0L;
        long singleScore = 0L;
        long multiScore = 0L;
        long judgeScore = 0L;

        for (HotExamPaperQuestion r : relations) {
            if (r == null) {
                continue;
            }
            long score = r.getScore() == null ? 0L : r.getScore();
            String t = r.getQuestionType();
            if ("1".equals(t)) {
                singleCount++;
                singleScore += score;
            } else if ("2".equals(t)) {
                multiCount++;
                multiScore += score;
            } else if ("3".equals(t)) {
                judgeCount++;
                judgeScore += score;
            }
        }

        vo.setSingleChoiceCount(singleCount);
        vo.setMultiChoiceCount(multiCount);
        vo.setJudgeCount(judgeCount);
        vo.setSingleChoiceScore(singleScore);
        vo.setMultiChoiceScore(multiScore);
        vo.setJudgeScore(judgeScore);
        return vo;
    }

    /**
     * 分页查询试卷库列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 试卷库分页列表
     */
    @Override
    public TableDataInfo<HotExamPaperVo> queryPageList(HotExamPaperBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HotExamPaper> lqw = buildQueryWrapper(bo);
        Page<HotExamPaperVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的试卷库列表
     *
     * @param bo 查询条件
     * @return 试卷库列表
     */
    @Override
    public List<HotExamPaperVo> queryList(HotExamPaperBo bo) {
        LambdaQueryWrapper<HotExamPaper> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HotExamPaper> buildQueryWrapper(HotExamPaperBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HotExamPaper> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(HotExamPaper::getId);
        // lqw.eq(bo.getCompanyId() != null, HotExamPaper::getCompanyId, bo.getCompanyId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), HotExamPaper::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getCategoryCode()), HotExamPaper::getCategoryCode, bo.getCategoryCode());
        lqw.eq(StringUtils.isNotBlank(bo.getTrainingTypeCode()), HotExamPaper::getTrainingTypeCode, bo.getTrainingTypeCode());
        lqw.eq(StringUtils.isNotBlank(bo.getTrainingSubtypeCodes()), HotExamPaper::getTrainingSubtypeCodes, bo.getTrainingSubtypeCodes());
        lqw.eq(bo.getQuestionCount() != null, HotExamPaper::getQuestionCount, bo.getQuestionCount());
        lqw.eq(bo.getTotalScore() != null, HotExamPaper::getTotalScore, bo.getTotalScore());
        lqw.eq(bo.getPassScore() != null, HotExamPaper::getPassScore, bo.getPassScore());
        lqw.eq(bo.getStatus() != null, HotExamPaper::getStatus, bo.getStatus());
        lqw.eq(bo.getIsDeleted() != null, HotExamPaper::getIsDeleted, bo.getIsDeleted());
        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
                HotExamPaper::getCreateTime, params.get("beginTime"), params.get("endTime"));
        return lqw;
    }

    /**
     * 新增试卷库
     *
     * @param bo 试卷库
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HotExamPaperBo bo) {
        HotExamPaper add = MapstructUtils.convert(bo, HotExamPaper.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改试卷库
     *
     * @param bo 试卷库
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HotExamPaperBo bo) {
        HotExamPaper update = MapstructUtils.convert(bo, HotExamPaper.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ExamPaperSaveQuestionsResultVo saveQuestions(ExamPaperSaveQuestionsBo bo) {
        if (bo == null || bo.getPaperId() == null) {
            throw new ServiceException("试卷ID不能为空");
        }
        if (StringUtils.isBlank(bo.getQuestionType())) {
            throw new ServiceException("题目类型不能为空");
        }
        String targetType = bo.getQuestionType();
        if (!"1".equals(targetType) && !"2".equals(targetType) && !"3".equals(targetType)) {
            throw new ServiceException("题目类型不合法");
        }

        HotExamPaper paper = baseMapper.selectById(bo.getPaperId());
        if (paper == null || (paper.getIsDeleted() != null && paper.getIsDeleted() == 1L)) {
            throw new ServiceException("试卷不存在");
        }

        Set<Long> questionIdSet = new LinkedHashSet<>();
        if (bo.getQuestions() != null) {
            for (Long id : bo.getQuestions()) {
                if (id != null) {
                    questionIdSet.add(id);
                }
            }
        }

        List<Long> questionIds = questionIdSet.stream().toList();
        Map<Long, HotQuestionBank> questionMap = questionIds.isEmpty() ? Map.of() :
                questionBankMapper.selectList(
                        Wrappers.<HotQuestionBank>lambdaQuery()
                                .in(HotQuestionBank::getId, questionIds)
                                .eq(HotQuestionBank::getIsDeleted, 0L)
                                .eq(paper.getCompanyId() != null, HotQuestionBank::getCompanyId, paper.getCompanyId())
                ).stream().filter(Objects::nonNull).collect(Collectors.toMap(HotQuestionBank::getId, q -> q, (a, b) -> a));

        if (questionMap.size() != questionIds.size()) {
            throw new ServiceException("题目列表包含不存在或已删除的题目");
        }

        for (HotQuestionBank q : questionMap.values()) {
            if (q == null || q.getQuestionType() == null) {
                throw new ServiceException("题目类型不能为空");
            }
            if (!targetType.equals(String.valueOf(q.getQuestionType()))) {
                throw new ServiceException("题目列表包含非当前题型的题目");
            }
        }

        examPaperQuestionMapper.delete(
                Wrappers.<HotExamPaperQuestion>lambdaQuery()
                        .eq(HotExamPaperQuestion::getPaperId, paper.getId())
                        .eq(HotExamPaperQuestion::getQuestionType, targetType)
        );

        List<HotExamPaperQuestion> relations = new ArrayList<>(questionIds.size());
        long sortOrder = 1L;
        for (Long questionId : questionIds) {
            HotQuestionBank q = questionMap.get(questionId);
            long score = q.getScore() == null ? 0L : q.getScore();

            HotExamPaperQuestion r = new HotExamPaperQuestion();
            r.setCompanyId(paper.getCompanyId());
            r.setPaperId(paper.getId());
            r.setQuestionId(questionId);
            r.setQuestionType(targetType);
            r.setSortOrder(sortOrder++);
            r.setScore(score);
            relations.add(r);
        }

        if (!relations.isEmpty()) {
            examPaperQuestionMapper.insertBatch(relations);
        }

        List<HotExamPaperQuestion> allRelations = examPaperQuestionMapper.selectList(
                Wrappers.<HotExamPaperQuestion>lambdaQuery()
                        .eq(HotExamPaperQuestion::getPaperId, paper.getId())
        );

        long questionCount = 0L;
        long totalScore = 0L;
        long singleCount = 0L;
        long multiCount = 0L;
        long judgeCount = 0L;
        long singleChoiceScore = 0L;
        long multiChoiceScore = 0L;
        long judgeScore = 0L;
        if (allRelations != null) {
            for (HotExamPaperQuestion r : allRelations) {
                if (r == null) {
                    continue;
                }
                questionCount++;
                long score = r.getScore() == null ? 0L : r.getScore();
                totalScore += score;
                if ("1".equals(r.getQuestionType())) {
                    singleCount++;
                    singleChoiceScore += score;
                } else if ("2".equals(r.getQuestionType())) {
                    multiCount++;
                    multiChoiceScore += score;
                } else if ("3".equals(r.getQuestionType())) {
                    judgeCount++;
                    judgeScore += score;
                }
            }
        }

        baseMapper.update(
                null,
                Wrappers.<HotExamPaper>lambdaUpdate()
                        .set(HotExamPaper::getQuestionCount, questionCount)
                        .set(HotExamPaper::getTotalScore, totalScore)
                        .eq(HotExamPaper::getId, paper.getId())
        );

        ExamPaperSaveQuestionsResultVo result = new ExamPaperSaveQuestionsResultVo();
        result.setQuestionCount(questionCount);
        result.setTotalScore(totalScore);
        result.setPassScore(paper.getPassScore());
        result.setSingleChoiceCount(singleCount);
        result.setMultiChoiceCount(multiCount);
        result.setJudgeCount(judgeCount);
        result.setSingleChoiceScore(singleChoiceScore);
        result.setMultiChoiceScore(multiChoiceScore);
        result.setJudgeScore(judgeScore);
        return result;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HotExamPaper entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除试卷库信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
