package com.seer.teach.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.admin.convert.ExampleQuestionsConvert;
import com.seer.teach.admin.convert.QuestionOptionsConvert;
import com.seer.teach.admin.request.CheckAndScoreReq;
import com.seer.teach.admin.request.ExampleQuestionsQueryReq;
import com.seer.teach.admin.request.ExampleQuestionsReq;
import com.seer.teach.admin.request.QuestionPreviewReq;
import com.seer.teach.admin.request.QuestionOptionsReq;
import com.seer.teach.admin.response.ExampleQuestionsResp;
import com.seer.teach.admin.response.QuestionOptionsResp;
import com.seer.teach.admin.service.AdminExampleQuestionsService;
import com.seer.teach.admin.util.RichTextTemplateProcessor;
import com.seer.teach.common.enums.ExampleQuestionTypesEnum;
import com.seer.teach.teacher.module.entity.ExampleQuestionsEntity;
import com.seer.teach.teacher.module.entity.QuestionOptionsEntity;
import com.seer.teach.teacher.module.entity.RichTextTemplateEntity;
import com.seer.teach.teacher.service.ExampleQuestionsService;
import com.seer.teach.teacher.service.QuestionOptionsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 例题管理服务实现类
 * </p>
 *
 * @author ZS
 * @since 2025-10-24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminExampleQuestionsServiceImpl implements AdminExampleQuestionsService {

    private final ExampleQuestionsService exampleQuestionsService;

    private final QuestionOptionsService questionOptionsService;
    
    private final RichTextTemplateProcessor RichTextTemplateProcessor;

    private final ExampleQuestionsConvert exampleQuestionsConvert = ExampleQuestionsConvert.INSTANCE;
    
    private final QuestionOptionsConvert questionOptionsConvert = QuestionOptionsConvert.INSTANCE;

    @Override
    public IPage<ExampleQuestionsResp> pageExampleQuestions(ExampleQuestionsQueryReq req) {
        log.info("分页查询例题列表, 查询参数: {}", req);
        Page<ExampleQuestionsEntity> page = new Page<>(req.getPageNo(), req.getPageSize());
        LambdaQueryWrapper<ExampleQuestionsEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (req.getKnowId() != null) {
            queryWrapper.eq(ExampleQuestionsEntity::getKnowId, req.getKnowId());
        }
        if (req.getType() != null) {
            queryWrapper.eq(ExampleQuestionsEntity::getType, req.getType());
        }
        if (req.getQuestion() != null && !req.getQuestion().isEmpty()) {
            queryWrapper.like(ExampleQuestionsEntity::getQuestion, req.getQuestion());
        }
        if(Objects.nonNull(req.getIsChecked())){
            queryWrapper.eq(ExampleQuestionsEntity::getIsChecked, req.getIsChecked());
        }
        if(CollUtil.isNotEmpty(req.getUpdateBy())){
            queryWrapper.in(ExampleQuestionsEntity::getUpdateBy, req.getUpdateBy());
        }
        if(StringUtils.hasText(req.getKeyword())){
            queryWrapper.likeRight(ExampleQuestionsEntity::getQuestion, req.getKeyword());
        }
        if(Objects.nonNull(req.getIsBlankHtml())){
            queryWrapper.isNull(req.getIsBlankHtml(),ExampleQuestionsEntity::getHtml);
        }
        IPage<ExampleQuestionsEntity> entityPage = exampleQuestionsService.page(page, queryWrapper);
        log.info("分页查询例题列表成功, 查询到 {} 条记录", entityPage.getRecords().size());
        IPage<ExampleQuestionsResp> result = entityPage.convert(exampleQuestionsConvert::toResp);
        if(CollectionUtil.isEmpty(result.getRecords())){
            return new Page<>(req.getPageNo(), req.getPageSize());
        }
        Set<Integer> questionIds = result.getRecords().stream().filter( item-> ExampleQuestionTypesEnum.CHOICE.getCode().intValue() == item.getType()).map(ExampleQuestionsResp::getId).collect(Collectors.toSet());
        if(CollectionUtil.isEmpty(questionIds)){
            return result;
        }
        List<QuestionOptionsEntity> options = questionOptionsService.getQuestionOptionsByQuestionIds(questionIds);
        if(CollectionUtil.isEmpty(options)){
            return result;
        }
        List<QuestionOptionsResp> questionOptionsRespList = QuestionOptionsConvert.INSTANCE.convertEntityListToRespList(options);
        Map<Integer, List<QuestionOptionsResp>> mappings = questionOptionsRespList.stream().collect(Collectors.groupingBy(QuestionOptionsResp::getQuestionId));
        result.getRecords().forEach(item->{
            List<QuestionOptionsResp> questionOptionsEntities = mappings.get(item.getId());
            if(CollectionUtil.isNotEmpty(questionOptionsEntities)){
                item.setOptions(questionOptionsEntities);
            }
        });
        return result;
    }

    @Override
    public ExampleQuestionsResp getExampleQuestionById(Integer id) {
        log.info("根据ID查询例题详情, ID: {}", id);
        ExampleQuestionsEntity entity = exampleQuestionsService.getById(id);
        ExampleQuestionsResp resp = exampleQuestionsConvert.toResp(entity);
        log.info("查询例题详情成功, ID: {}", id);
        if(ExampleQuestionTypesEnum.CHOICE.getCode().intValue() == resp.getType()){
            List<QuestionOptionsEntity> options = questionOptionsService.getQuestionOptionsByQuestionId(id);
            if(CollectionUtil.isNotEmpty( options)){
                List<QuestionOptionsResp> questionOptionsRespList = QuestionOptionsConvert.INSTANCE.convertEntityListToRespList(options);
                resp.setOptions(questionOptionsRespList);
            }
        }
        return resp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addExampleQuestion(ExampleQuestionsReq req) {
        log.info("新增例题, 请求参数: {}", req);
        ExampleQuestionsEntity entity = exampleQuestionsConvert.toEntity(req);
        boolean result = exampleQuestionsService.save(entity);
        
        // 如果是选择题且包含选项，则保存选项
        if (result && ExampleQuestionTypesEnum.CHOICE.getCode().equals(req.getType()) 
                && CollectionUtil.isNotEmpty(req.getOptions())) {
            saveQuestionOptions(entity.getId(), req.getOptions());
        }
        
        log.info("新增例题结果: {}, 例题ID: {}", result, entity.getId());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSaveGeneratedExampleQuestions(List<ExampleQuestionsReq> reqList) {
        log.info("批量保存生成的例题, 请求参数数量: {}", reqList.size());
        if (CollectionUtil.isEmpty(reqList)) {
            log.warn("批量保存生成的例题请求参数为空");
            return false;
        }
        
        List<ExampleQuestionsEntity> entities = reqList.stream()
                .map(exampleQuestionsConvert::toEntity)
                .collect(Collectors.toList());
        
        boolean result = exampleQuestionsService.saveBatch(entities);
        
        // 如果保存成功，处理选择题的选项
        if (result) {
            for (int i = 0; i < entities.size(); i++) {
                ExampleQuestionsEntity entity = entities.get(i);
                ExampleQuestionsReq req = reqList.get(i);
                
                // 如果是选择题且包含选项，则保存选项
                if (ExampleQuestionTypesEnum.CHOICE.getCode().equals(req.getType()) 
                        && CollectionUtil.isNotEmpty(req.getOptions())) {
                    saveQuestionOptions(entity.getId(), req.getOptions());
                }
            }
        }
        
        log.info("批量保存生成的例题结果: {}", result);
        return result;
    }

    /**
     * 保存题目选项
     * 
     * @param questionId 题目ID
     * @param options 选项列表
     */
    private void saveQuestionOptions(Integer questionId, List<QuestionOptionsReq> options) {
        List<QuestionOptionsEntity> optionEntities = options.stream()
                .map(option -> {
                    QuestionOptionsEntity optionEntity = questionOptionsConvert.convertReqToEntity(option);
                    optionEntity.setQuestionId(questionId);
                    return optionEntity;
                })
                .collect(Collectors.toList());
        
        questionOptionsService.saveBatch(optionEntities);
        log.info("保存题目选项成功，题目ID: {}, 选项数量: {}", questionId, optionEntities.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateExampleQuestion(Integer id, ExampleQuestionsReq req) {
        log.info("更新例题, 例题ID: {}, 请求参数: {}", id, req);
        ExampleQuestionsEntity entity = exampleQuestionsConvert.toEntity(req);
        if (Objects.isNull(exampleQuestionsService.getById(id))) {
            log.warn("更新例题失败, 例题不存在, 例题ID: {}", id);
            return false;
        }
        entity.setId(id);
        boolean result = exampleQuestionsService.updateById(entity);
        log.info("更新例题结果: {}, 例题ID: {}", result, id);
        return result;
    }

    @Override
    public boolean updateExampleQuestionCheckAndScore(Integer id, CheckAndScoreReq req) {
        ExampleQuestionsEntity entity = new ExampleQuestionsEntity();
        entity.setId(id);
        entity.setIsChecked(req.getIsChecked());
        entity.setScore(req.getScore());
        return exampleQuestionsService.updateById(entity);
    }

    @Override
    public boolean batchUpdateExampleQuestionCheck(List<Integer> ids, Integer isChecked) {
        List<ExampleQuestionsEntity> entities = ids.stream().map(id -> {
            ExampleQuestionsEntity entity = new ExampleQuestionsEntity();
            entity.setId(id);
            entity.setIsChecked(isChecked);
            return entity;
        }).collect(Collectors.toList());
        
        return exampleQuestionsService.updateBatchById(entities);
    }

    /**
     * 删除例题及其关联的选项
     *
     * @param id 要删除的例题ID
     * @return 是否删除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteExampleQuestion(Integer id) {
        log.info("开始删除ID为{}的例题", id);
        
        // 先检查例题是否存在
        ExampleQuestionsEntity entity = exampleQuestionsService.getById(id);
        if (Objects.isNull(entity)) {
            log.warn("尝试删除例题时未找到对应记录，例题ID：{}", id);
            return false;
        }
        
        // 删除关联的题目选项
        boolean deletedOptions = questionOptionsService.remove(
                new LambdaQueryWrapper<QuestionOptionsEntity>()
                        .eq(QuestionOptionsEntity::getQuestionId, id));
        log.info("删除例题选项完成，结果：{}", deletedOptions);
        
        // 删除例题本身
        boolean result = exampleQuestionsService.removeById(id);
        
        if (result) {
            log.info("例题删除成功，例题ID：{}", id);
        } else {
            log.error("例题删除失败，例题ID：{}", id);
        }
        return result;
    }

    @Override
    public boolean updateExampleQuestionsHtmlByKnowledgePointIds(Collection<Integer> knowledgePointIds, RichTextTemplateEntity richTextTemplate) {
        try {
            // 获取知识点下的所有例题
            List<ExampleQuestionsEntity> questions = exampleQuestionsService.getQuestionsByKnowleIds(knowledgePointIds);
            
            if (CollectionUtil.isEmpty(questions)) {
                log.info("没有找到相关例题，无需更新");
                return true;
            }
            // 批量更新例题的html字段
            List<ExampleQuestionsEntity> updatedQuestions = new ArrayList<>();
            for (ExampleQuestionsEntity question : questions) {
                // 构造预览请求参数
                QuestionPreviewReq previewReq = new QuestionPreviewReq();
                previewReq.setQuestion(question.getQuestion());
                previewReq.setAnswer(question.getAnswer());
                previewReq.setSolution(question.getSolution());
                previewReq.setType(question.getType());
                
                // 如果是选择题，获取选项
                if (ExampleQuestionTypesEnum.CHOICE.getCode().equals(question.getType())) {
                    List<QuestionOptionsEntity> options = questionOptionsService.getQuestionOptionsByQuestionId(question.getId());
                    if (CollectionUtil.isNotEmpty(options)) {
                        List<String> optionContents = options.stream()
                                .map(QuestionOptionsEntity::getContent)
                                .collect(Collectors.toList());
                        previewReq.setOptions(optionContents);
                    }
                }
                
                // 使用模板服务生成html
                String html = RichTextTemplateProcessor.processTemplate(richTextTemplate,previewReq);
                
                // 设置html字段
                question.setHtml(html);
                updatedQuestions.add(question);
            }
            // 批量更新
            boolean result = exampleQuestionsService.updateBatchById(updatedQuestions);
            log.info("更新例题富文本完成，共更新 {} 条记录，结果: {}", updatedQuestions.size(), result);
            return result;
        } catch (Exception e) {
            log.error("更新例题富文本时发生错误", e);
            return false;
        }
    }
}