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

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.seer.teach.admin.convert.KnowledgePointsConvert;
import com.seer.teach.admin.request.GenerateTaskReq;
import com.seer.teach.admin.response.TeachTextsResp;
import com.seer.teach.admin.service.TeachTextGenerationService;
import com.seer.teach.admin.util.PromptBuilder;
import com.seer.teach.common.enums.AiScenarioCodeEnum;
import com.seer.teach.teacher.module.entity.TeachGoalsEntity;
import com.seer.teach.teacher.module.entity.TeachMethodsEntity;
import com.seer.teach.teacher.module.entity.TeachTextsEntity;
import com.seer.teach.teacher.module.param.KnowledgePointSearchParam;
import com.seer.teach.teacher.service.KnowledgePointQueryService;
import com.seer.teach.teacher.service.TeachGoalsService;
import com.seer.teach.teacher.service.TeachMethodsService;
import com.seer.teach.teacher.service.TeachTextsService;
import com.seer.teach.teacher.service.platform.LlmResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 讲课稿生成服务实现类
 * </p>
 *
 * @author Lingma
 * @since 2025-12-11
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TeachTextGenerationServiceImpl extends AbstractGenerationService<TeachTextsResp, GenerateTaskReq, TeachTextsEntity> implements TeachTextGenerationService {

    private final KnowledgePointQueryService knowledgePointQueryService;

    private final TeachGoalsService teachGoalsService;

    private final TeachTextsService teachTextsService;

    private final TeachMethodsService teachMethodsService;

    @Override
    public List<TeachTextsResp> generateTeachTexts(GenerateTaskReq req) {
        log.info("根据教学目标生成讲课稿, 请求参数: {}", req);

        // 1. 根据教学目标ID查询对应的教学目标
        Integer goalId = req.getGoalId();
        TeachGoalsEntity teachGoal = teachGoalsService.getById(goalId);
        if (Objects.isNull(teachGoal)) {
            log.warn("未找到教学目标，ID: {}", goalId);
            return Collections.emptyList();
        }
        // 2. 调用大模型生成讲课稿
        List<TeachTextsResp> generatedTexts = callLLMToGenerateTeachText(teachGoal, req);

        log.info("生成讲课稿完成，共生成 {} 个讲课稿", generatedTexts.size());
        return generatedTexts;
    }

    @Override
    public Integer generateAndSaveAllTeachTexts(GenerateTaskReq req) {
        // 1. 查询所有教学目标
        KnowledgePointSearchParam params = KnowledgePointsConvert.INSTANCE.generateReq2KnowledgePointSearchParam(req);
        Collection<Integer> knowIds = knowledgePointQueryService.getKnowIdsByConditions(params);
        if (CollectionUtil.isEmpty(knowIds)) {
            log.warn("未找到对应的知识点");
            return 0;
        }
        Collection<TeachGoalsEntity> teachGoals = teachGoalsService.list(new LambdaQueryWrapper<TeachGoalsEntity>().in(TeachGoalsEntity::getKnowId, knowIds));
        if (CollectionUtil.isEmpty(teachGoals)) {
            log.warn("未找到对应的教学目标");
            return 0;
        }
        log.info("查询到的教学目标数量: {}", teachGoals.size());
        int totalCount = 0;
        // 2. 处理教学目标
        for (TeachGoalsEntity teachGoal : teachGoals) {
            // 检查任务是否被取消
            String taskId = getTaskIdFromRequest(req);
            if (isThreadInterrupted() || isTaskCancelled(taskId)) {
                log.info("任务被中断或取消，停止执行");
                return totalCount;
            }
            long counted = teachTextsService.count(new LambdaQueryWrapper<TeachTextsEntity>()
                    .eq(TeachTextsEntity::getGoalId, teachGoal.getId()));

            // 如果已经有讲课稿，则跳过
            if (counted > 0) {
                log.info("教学目标: {} 已存在讲课稿，跳过该教学目标", teachGoal.getId());
                continue;
            }

            log.info("教学目标: {} 开始生成讲课稿", teachGoal.getId());

            req.setGoalId(teachGoal.getId());
            totalCount += executeBatchProcess(
                    req,
                    this::generateTeachTexts,
                    this::saveGeneratedTeachTexts
            );
        }

        log.info("生成讲课稿任务完成，总共处理 {} 个教学目标", totalCount);
        return totalCount;
    }

    /**
     * 保存生成的讲课稿
     *
     * @param texts 生成的讲课稿列表
     */
    private void saveGeneratedTeachTexts(List<TeachTextsResp> texts) {
        if (texts.isEmpty()) {
            return;
        }
        List<TeachTextsEntity> textItems = new ArrayList<>();
        for (TeachTextsResp text : texts) {
            TeachTextsEntity item = new TeachTextsEntity();
            item.setGoalId(text.getGoalId());
            item.setSort(text.getSort());
            item.setText(text.getText());
            item.setMethodId(text.getMethodId());
            item.setVideoContent(text.getVideoContent());
            item.setIsDefault(0);
            textItems.add(item);
        }
        boolean result = teachTextsService.saveBatch(textItems);
        log.info("批量保存讲课稿结果: {}", result);
    }

    /**
     * 调用大模型生成讲课稿
     *
     * @param teachGoal 教学目标
     * @param req       生成讲课稿参数
     * @return 生成的讲课稿列表
     */
    private List<TeachTextsResp> callLLMToGenerateTeachText(TeachGoalsEntity teachGoal, GenerateTaskReq req) {
        log.info("调用大模型生成讲课稿，教学目标: {}", teachGoal.getId());
        List<TeachMethodsEntity> methods = teachMethodsService.list();
        // 构建提示词
        String prompt = PromptBuilder.buildPromptForTeachTextGeneration(teachGoal,methods, req);

        log.info("调用大模型生成讲课稿，提示词: {}", prompt);

        // 调用大模型API生成讲课稿
        Map<String, Object> params = new HashMap<>();
        if (Objects.nonNull(req.getTaskId())) {
            params.putIfAbsent("taskId", req.getTaskId());
        }
        LlmResponse result = callLLM(
                AiScenarioCodeEnum.GENERATE_TEACH_TEXTS_FROM_GOALS.getCode(),
                prompt,
                params,
                req.getUserId());

        if (Objects.isNull(result)) {
            log.warn("调用大模型生成讲课稿失败，返回结果为空");
            return Collections.emptyList();
        }

        // 使用新的泛型方法解析响应
        List<TeachTextsResp> texts = new ArrayList<>();
        for (LlmResponse.Choice choice : result.getChoices()) {
            LlmResponse.Message message = choice.getMessage();
            if (Objects.isNull(message)) {
                log.warn("调用大模型生成讲课稿失败，返回结果中 'message' 为空");
                continue;
            }
            String content = message.getContent();
            List<TeachTextsResp> resultList = parseLLMResponse(content, textNode -> {
                TeachTextsResp textResp = new TeachTextsResp();
                // 解析基本字段
                textResp.setText(getStringValue(textNode, "text"));
                textResp.setSort(getIntValue(textNode, "sort"));
                textResp.setIsDefault(getIntValue(textNode, "isDefault",0));
                textResp.setMethodId(getIntValue(textNode, "methodId"));
                textResp.setVideoContent(getStringValue(textNode, "videoContent"));
                textResp.setGoalId(teachGoal.getId());
                return textResp;
            });
            texts.addAll(resultList);
        }
        return texts;
    }

    @Override
    protected String getTaskIdFromRequest(GenerateTaskReq request) {
        return request.getTaskId();
    }
}