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

import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.enums.teacher.ModuleEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.teacher.common.req.DoExerciseReq;
import com.seer.teach.teacher.common.req.StudyReq;
import com.seer.teach.teacher.common.resp.DoExerciseResp;
import com.seer.teach.teacher.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 学习服务实现类
 * <p>
 * 提供学生学习相关功能的统一入口，包括普通学习、带问题的学习、做题挑战以及继续学习等操作。
 * 使用策略模式根据不同的学习类型调用对应的服务方法。
 * </p>
 *
 * @author Captain
 * @since 2025-10-08 14:47
 */
@Service
@RequiredArgsConstructor
public class StudyServiceImpl implements StudyService {

    /**
     * 学习处理器映射表
     * key：学习类型编码（如复习、预习）
     * value：处理该类型学习请求的方法引用
     */
    private Map<Integer, Consumer<StudyReq>> studyHandlers;

    /**
     * 挑战处理器映射表
     * key：学习类型编码
     * value：执行练习任务并返回结果列表的方法引用
     */
    private Map<Integer, Function<DoExerciseReq, DoExerciseResp>> doExerciseHandlers;

    private final EvaluationTasksService evaluationTasksService;

    private final LessonsService lessonsService;

    /**
     * 初始化所有处理器映射表，在对象构造完成后自动执行
     */
    @PostConstruct
    public void initHandlerMap() {
        initStudyHandler();
        initDoExerciseHandler();
    }

    private void initDoExerciseHandler() {
        doExerciseHandlers = new HashMap<>();
        doExerciseHandlers.put(ModuleEnum.EVALUATION.getCode(), evaluationTasksService::doExercise);
    }

    private void initStudyHandler() {
        studyHandlers = new HashMap<>();
        studyHandlers.put(ModuleEnum.LESSON.getCode(), lessonsService::startLesson);
    }

    @Override
    public void study(StudyReq params) {
        Consumer<StudyReq> studyHandler = studyHandlers.get(params.getType());
        AssertUtils.notNull(studyHandler, ResultCodeEnum.NOT_FOUND);
        studyHandler.accept(params);
    }

    /**
     * 执行指定类型的练习挑战，并返回练习结果
     *
     * @param params 包含练习相关信息的请求对象
     * @return 返回练习过程中产生的资源路径列表
     */
    @Override
    public DoExerciseResp doExercise(DoExerciseReq params) {
        Function<DoExerciseReq, DoExerciseResp> challengeHandler = doExerciseHandlers.get(params.getType());
        AssertUtils.notNull(challengeHandler, ResultCodeEnum.NOT_FOUND);
        return challengeHandler.apply(params);
    }

}
