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

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.iot.api.UserDeviceServiceApi;
import com.seer.teach.teacher.common.llm.req.LlmGetPlanQuestionReq;
import com.seer.teach.teacher.common.req.DoExerciseReq;
import com.seer.teach.teacher.common.utils.TeacherUtils;
import com.seer.teach.teacher.convert.QuestionConvert;
import com.seer.teach.teacher.module.entity.BankQuestionsEntity;
import com.seer.teach.teacher.module.entity.PlanQuestionsEntity;
import com.seer.teach.teacher.module.entity.PlansEntity;
import com.seer.teach.teacher.module.mapper.PlansMapper;
import com.seer.teach.teacher.service.BankQuestionsService;
import com.seer.teach.teacher.service.LlmRequestService;
import com.seer.teach.teacher.service.PlanQuestionsService;
import com.seer.teach.teacher.service.PlansService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 黑马计划服务实现类，提供学习计划的获取、开始学习、进度同步、挑战题生成等功能。
 * </p>
 *
 * @author Wang
 * @since 2025-08-08 14:18:13
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PlansServiceImpl extends ServiceImpl<PlansMapper, PlansEntity> implements PlansService {

    private final LlmRequestService llmRequestService;

    private final UserDeviceServiceApi userDeviceServiceApi;

    private final PlanQuestionsService planQuestionsService;

    private final BankQuestionsService bankQuestionsService;


    /**
     * 根据设备标识和练习请求执行一次练习任务。
     * 包括：获取用户ID、查找对应计划、请求大模型生成题目、更新计划信息、
     * 查询题库中的具体题目内容、建立计划与题目的关联关系，并通过WebSocket推送题目数据。
     *
     * @param device        设备标识
     * @param doExerciseReq 练习请求参数，包括计划ID等信息
     * @return 题目HTML内容字符串列表
     */
    @Override
    public List<String> doExercise(String device, DoExerciseReq doExerciseReq) {
        // 获取用户ID
        Integer userId = userDeviceServiceApi.getUserIdByDevice(device);

        // 获取指定计划详情
        PlansEntity plan = getById(doExerciseReq.getId());

        // 请求大模型获取该计划对应的题目ID列表
        List<Integer> questionIds = llmRequestService.requestLlmGetPlanQuestions(new LlmGetPlanQuestionReq(TeacherUtils.generateSessionId(plan.getModulePlanId(), userId), plan.getModulePlanId(), userId));

        // 更新计划相关信息（如题目数量）
        updatePlan(plan, questionIds);

        // 批量查询题目详细信息
        List<BankQuestionsEntity> questions = bankQuestionsService.listByIds(questionIds);

        // 建立计划与题目的关联关系
        insertPlanQuestion(plan.getId(), questions);

        // 提取所有题目的HTML内容作为结果返回
        return questions.stream().map(BankQuestionsEntity::getQuestionHtml).collect(Collectors.toList());
    }

    /**
     * 更新计划信息
     *
     * @param plan      计划实体对象，包含需要更新的计划信息
     * @param llmResult LLM处理结果列表，用于获取问题数量等信息
     */
    private void updatePlan(PlansEntity plan, List<Integer> llmResult) {
        // 更新计划中的题目数量和开始时间
        plan.setQuestionCount(llmResult.size());
        plan.setStartTime(LocalDateTime.now());
        updateById(plan);
    }

    /**
     * 插入计划问题记录
     * 将题库中的问题转换为计划问题实体，并批量保存到数据库中
     *
     * @param recordId  计划记录ID，用于关联计划问题
     * @param questions 题库问题实体列表，需要转换为计划问题
     */
    private void insertPlanQuestion(Integer recordId, List<BankQuestionsEntity> questions) {
        // 将题库问题转换为计划问题实体并设置默认状态
        List<PlanQuestionsEntity> savQuestions = questions.stream()
                .map(q -> QuestionConvert.INSTANCE.toPlanQuestionEntity(q.getId(), recordId, "未回答"))
                .collect(Collectors.toList());
        // 批量保存计划问题记录
        planQuestionsService.saveBatch(savQuestions);
    }

}