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.AdminTeachGoalConvert;
import com.seer.teach.admin.request.GenerateTaskReq;
import com.seer.teach.admin.response.TeachGoalsResp;
import com.seer.teach.admin.service.TeachGoalGenerationService;
import com.seer.teach.admin.util.PromptBuilder;
import com.seer.teach.teacher.module.entity.KnowledgePointEntity;
import com.seer.teach.teacher.module.entity.MaterialEntity;
import com.seer.teach.teacher.module.entity.TeachGoalsEntity;
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.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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 教学目标生成服务实现类
 * </p>
 *
 * @author Lingma
 * @since 2025-12-04
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TeachGoalGenerationServiceImpl extends AbstractGenerationService<TeachGoalsResp, GenerateTaskReq, TeachGoalsEntity> implements TeachGoalGenerationService {

    private final KnowledgePointQueryService knowledgePointQueryService;
    
    private final TeachGoalsService teachGoalsService;
    
    @Override
    public List<TeachGoalsResp> generateTeachGoals(GenerateTaskReq req) {
        log.info("根据知识点生成教学目标, 请求参数: {}", req);

        // 1. 根据知识点ID查询对应的知识点
        Integer knowId = req.getKnowId();
        KnowledgePointEntity knowledgePoint = knowledgePointQueryService.getKnowledgePointByKnowId(knowId);
        if (Objects.isNull(knowledgePoint)) {
            log.warn("未找到知识点，ID: {}", knowId);
            return Collections.emptyList();
        }
        
        // 设置请求参数
        req.setGradeType(knowledgePoint.getGradeType());
        req.setSubjectId(knowledgePoint.getSubjectId());
        req.setSummary(knowledgePoint.getSummary());
        
        if (CollectionUtil.isEmpty(req.getGradeIds())) {
            Collection<MaterialEntity> materials = knowledgePointQueryService.getMaterialListByKnowId(knowId);
            if (CollectionUtil.isNotEmpty(materials)) {
                req.setGradeIds(materials.stream().map(MaterialEntity::getGradeId).collect(Collectors.toSet()));
            }
        }

        // 2. 调用大模型生成教学目标
        List<TeachGoalsResp> generatedGoals = callLLMToGenerateTeachGoals(knowledgePoint, req);

        log.info("生成教学目标完成，共生成 {} 个教学目标", generatedGoals.size());
        return generatedGoals;
    }

    @Override
    public Integer generateAndSaveAllTeachGoals(GenerateTaskReq req) {
        // 1. 查询所有知识点
        Integer count = req.getCount();
        Collection<Integer> knowIds = new HashSet<>();
        if (Objects.nonNull(req.getSubjectId()) || Objects.nonNull(req.getVersionId()) || Objects.nonNull(req.getGradeId())) {
            KnowledgePointSearchParam knowledgePointSearchParam = AdminTeachGoalConvert.INSTANCE.generateTeachGoalReq2KnowledgePointSearchParam(req);
            log.info("根据条件查询知识点，参数: {}", knowledgePointSearchParam);
            Collection<Integer> queryKnowIds = knowledgePointQueryService.getKnowIdsByConditions(knowledgePointSearchParam);
            if (CollectionUtil.isEmpty(queryKnowIds)) {
                return 0;
            }
            knowIds.addAll(queryKnowIds);
        }
        Collection<KnowledgePointEntity> knowledgePoints = knowledgePointQueryService.getKnowledgePointListByIdsOrElseAll(knowIds);

        int totalCount = 0;
        // 2. 处理知识点
        for (KnowledgePointEntity knowledgePoint : knowledgePoints) {
            // 检查任务是否被取消
            String taskId = getTaskIdFromRequest(req);
            if (isThreadInterrupted() || isTaskCancelled(taskId)) {
                log.info("任务被中断或取消，停止执行");
                return totalCount;
            }
            long counted = teachGoalsService.count(new LambdaQueryWrapper<>(TeachGoalsEntity.class)
                    .eq(TeachGoalsEntity::getKnowId, knowledgePoint.getId()));
            
            if (counted >= count) {
                log.info("知识点: {} 已存在的教学目标总数: {}，要求的目标数量：{},已经超过，跳过该知识点", knowledgePoint.getKnowledgePointName(), counted, count);
                continue;
            }
            
            log.info("知识点: {} 已生成教学目标数量: {}，开始生成教学目标", knowledgePoint.getKnowledgePointName(), counted);
            int remainingCount = count - Math.toIntExact(counted);
            int actualCount = remainingCount > 3 ? 3 : 1;
            req.setCount(actualCount);
            req.setKnowId(knowledgePoint.getId());
            totalCount += executeBatchProcess(
                    req,
                    this::generateTeachGoals,
                    this::saveGeneratedTeachGoals
            );
        }
        
        log.info("生成教学目标任务完成，总共生成 {} 个教学目标", totalCount);
        return totalCount;
    }

    /**
     * 保存生成的教学目标
     * 
     * @param goals 生成的教学目标列表
     */
    private void saveGeneratedTeachGoals(List<TeachGoalsResp> goals) {
        if (goals.isEmpty()) {
            return;
        }
        // 转换教学目标列表
        List<TeachGoalsEntity> goalItems = new ArrayList<>();
        for (TeachGoalsResp goal : goals) {
            TeachGoalsEntity item = new TeachGoalsEntity();
            item.setSort(goal.getSort());
            item.setGoal(goal.getGoal());
            item.setPoint(goal.getPoint());
            item.setKnowId(goal.getKnowId());
            goalItems.add(item);
        }
        // 保存到数据库
        teachGoalsService.saveBatch(goalItems);
    }

    /**
     * 调用大模型生成教学目标
     *
     * @param knowledgePoint 知识点
     * @param req            生成教学目标参数
     * @return 生成的教学目标列表
     */
    private List<TeachGoalsResp> callLLMToGenerateTeachGoals(KnowledgePointEntity knowledgePoint, GenerateTaskReq req) {
        Integer count = req.getCount();
        // 构建提示词
        String prompt = PromptBuilder.buildPromptForTeachGoalGeneration(knowledgePoint, count, req);

        log.info("调用大模型生成教学目标，提示词长度: {}", prompt.length());

        // 调用大模型API生成教学目标
        Map<String, Object> params = new HashMap<>();
        if (Objects.nonNull(req.getTaskId())) {
            params.putIfAbsent("taskId", req.getTaskId());
        }
        LlmResponse result = callLLM(req.getScenarioCode(), prompt, params, req.getUserId());
        if (Objects.isNull(result)) {
            log.warn("调用大模型生成教学目标失败，返回结果为空");
            return Collections.emptyList();
        }
        
        // 使用新的泛型方法解析响应
        List<TeachGoalsResp> goals = 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<TeachGoalsResp> resultList = parseLLMResponse(content, goalNode -> {
                TeachGoalsResp goalResp = new TeachGoalsResp();
                // 解析基本字段
                goalResp.setGoal(getStringValue(goalNode, "goal"));
                goalResp.setPoint(getStringValue(goalNode, "point"));
                goalResp.setKnowId(knowledgePoint.getId());
                goalResp.setSort(getIntValue(goalNode, "sort"));
                return goalResp;
            });
            goals.addAll(resultList);
        }
        return goals;
    }
    
    @Override
    protected String getTaskIdFromRequest(GenerateTaskReq request) {
        return request.getTaskId();
    }
}