package com.ruoyi.web.controller.learn;

import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.content.VistorContextHolder;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.AjaxResult2;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.ExamType;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.dz.domain.DzControl;
import com.ruoyi.dz.domain.DzSubject;
import com.ruoyi.dz.service.IDzControlService;
import com.ruoyi.dz.service.IDzSubjectService;
import com.ruoyi.enums.PaperBuildStatus;
import com.ruoyi.enums.QuestionType;
import com.ruoyi.learn.domain.*;
import com.ruoyi.learn.service.ILearnPaperService;
import com.ruoyi.learn.service.ILearnTestPaperService;
import com.ruoyi.syzy.domain.BBusiWishUniversities;
import com.ruoyi.syzy.mapper.BBusiWishUniversitiesMapper;
import com.ruoyi.web.service.LearnTeacherService;
import com.ruoyi.web.service.PaperService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/learn/teaching")
@Api(tags = "后台-学习 - 老师业务")
public class LearnTeacherController extends BaseController {
    private final IDzControlService dzControlService;
    private final IDzSubjectService dzSubjectService;
    private final LearnTeacherService learnTeacherService;
    private final PaperService paperService;
    private final ILearnPaperService learnPaperService;
    private final ILearnTestPaperService testPaperService;
    private final BBusiWishUniversitiesMapper busiWishUniversitiesMapper;

    public LearnTeacherController(IDzControlService dzControlService, IDzSubjectService dzSubjectService, LearnTeacherService learnTeacherService, PaperService paperService, ILearnPaperService learnPaperService, ILearnTestPaperService testPaperService, BBusiWishUniversitiesMapper busiWishUniversitiesMapper) {
        this.dzControlService = dzControlService;
        this.dzSubjectService = dzSubjectService;
        this.learnTeacherService = learnTeacherService;
        this.paperService = paperService;
        this.learnPaperService = learnPaperService;
        this.testPaperService = testPaperService;
        this.busiWishUniversitiesMapper = busiWishUniversitiesMapper;
    }


    @GetMapping(value = "examTypes")
    @Anonymous
    @ApiOperation("考生类型列表")
    public AjaxResult examTypes(@RequestParam String location)
    {
        DzControl cond = new DzControl();
        cond.setIsValid(1);
        cond.setLocation(location);
        List<DzControl> list = dzControlService.selectDzControlList(cond);
        String examTypes;
        if(CollectionUtils.isEmpty(list) || StringUtils.isBlank(examTypes = list.get(0).getExamTypes())) {
            return AjaxResult.success(Collections.emptyList());
        }
        return AjaxResult.success(Arrays.stream(examTypes.split(",")).map(t -> {
            JSONObject o = new JSONObject();
            o.put("dictValue", t);
            o.put("dictLabel", ExamType.valueOf(t).title());
            return o;
        }).collect(Collectors.toList()));
    }

    @GetMapping("/subjects")
    @ApiOperation("科目列表")
    public AjaxResult2<List<DzSubject>> subjects(@RequestParam @ApiParam("考生类型") ExamType examType)
    {
        DzSubject sCond = new DzSubject();
        sCond.setExamTypes(examType.name());
        List<DzSubject> list = dzSubjectService.selectDzSubjectList(sCond);
        return AjaxResult2.success(list);
    }

    @GetMapping("/knowledges")
    @ApiOperation("知识点列表")
    public AjaxResult knowledges(@ApiParam("类型 ExactIntelligent/FullIntelligent/ExactHand/FullHand") @RequestParam String buildType,
                                 @ApiParam("科目ID") @RequestParam(required = false) Long subjectId,
                                 @ApiParam("专业计划ID") @RequestParam(required = false) Long majorPlanId,
                                 @ApiParam("考生类型") @RequestParam(required = false) String examType)
    {
        Set<Long> knowledgeIdSet = null;
        if("ExactHand".equals(buildType)) {
            knowledgeIdSet = learnTeacherService.getKnowledgeIdSet(subjectId, majorPlanId, null, examType);
        }
        return AjaxResult.success(learnTeacherService.getKnowledgeTree(examType, subjectId, knowledgeIdSet, null, null));
    }

    @GetMapping(value = "classStatistic")
    @ApiOperation("班级生成统计")
    public AjaxResult classStatistic(TestPaperVO.TestPaperBuildReq req)
    {
        if (NumberUtils.isPositive(req.getMajorPlanId())) {
            req.setMajorGroup(null);
        }
        return AjaxResult.success(learnTeacherService.getClassesBuildStats(req, getTeacherId()));
    }

    @GetMapping(value = "getClassesBuildStatsDetail")
    @ApiOperation("班级组卷统计详情（学生列表）")
    public AjaxResult getClassesBuildStatsDetail(
            @ApiParam("组卷类型") @RequestParam String buildType,
            @ApiParam("批次ID") @RequestParam(required = false) Integer batchId,
            @ApiParam("班级ID") @RequestParam(required = false) Long classId,
            @ApiParam("统计类型：send/total/unexact/unfinish/unsend") @RequestParam String statType,
            @ApiParam("考生类型") @RequestParam(required = false) String examType,
            @ApiParam("科目ID") @RequestParam(required = false) Long subjectId,
            @ApiParam("院校ID") @RequestParam(required = false) Long universityId,
            @ApiParam("专业组") @RequestParam(required = false) String majorGroup,
            @ApiParam("专业计划ID") @RequestParam(required = false) Long majorPlanId)
    {
        TestPaperVO.TestPaperBuildReq req = new TestPaperVO.TestPaperBuildReq();
        req.setBuildType(buildType);
        req.setBatchId(batchId);
        req.setClassId(classId);
        req.setExamType(examType);
        req.setSubjectId(subjectId);
        req.setUniversityId(universityId);
        req.setMajorGroup(majorGroup);
        req.setMajorPlanId(majorPlanId);
        List<JSONObject> list = learnTeacherService.getClassesBuildStatsDetail(req, getTeacherId(), statType);
        return AjaxResult.success(list);
    }


    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
    @GetMapping("build/getBuiltPaper")
    @ApiOperation("获取已组卷详情")
    public AjaxResult getBuiltPaper(TestPaperVO.TestPaperBuildReq req) {
        req.setTeacherId(getTeacherId());
        List<LearnTestPaper> testPaperList = learnTeacherService.getBuiltTestPaper(req);
        if (CollectionUtils.isEmpty(testPaperList)) {
            return AjaxResult.success(Collections.emptyList());
        }
        List<JSONObject> resultList = new ArrayList<>();

        Map uCond = new HashMap();
        uCond.put("ids", testPaperList.stream().map(LearnTestPaper::getUniversityId).collect(Collectors.toSet()));
        Map<Long, BBusiWishUniversities> universityMap = busiWishUniversitiesMapper.selectBBusiWishUniversitiesListSimpleByIds(uCond).stream().collect(Collectors.toMap(BBusiWishUniversities::getId, Function.identity()));
        for(LearnTestPaper learnTestPaper : testPaperList) {
            PaperVO paperVO = paperService.loadPaper(learnTestPaper.getPaperId());
            JSONObject root = JSONObject.from(paperVO);
            root.remove("id");
            BBusiWishUniversities u = universityMap.get(learnTestPaper.getUniversityId());
            if(null != u) {
                String paperName = paperVO.getPaperName().replaceAll(paperVO.getDirectKey(), "");
                paperName += u.getName() + "_" + ExamType.valueOf(learnTestPaper.getExamType()).title();
                root.put("paperName", paperName);
            }
            root.put("paperId", learnTestPaper.getPaperId());
            resultList.add(root);
        }

        return AjaxResult.success(resultList);
    }

    @GetMapping("/getPaperClassRecords")
    @ApiOperation("组卷记录")
    public TableDataInfo getPaperClassRecords(TestPaperVO.TestPaperBuildReq req)
    {
        startPage();
        List<JSONObject> list = learnTeacherService.getPaperClassRecords(req, SecurityUtils.getLoginUser().getUser().getUserTypeId());
        list.stream().forEach(o -> {
            o.put("buildType", req.getBuildType());
        });
        return getDataTable(list);
    }

    @GetMapping("/getPapers")
    @ApiOperation("获取试卷列表")
    public TableDataInfo getPapers(TestPaperVO.TestPaperBuildReq req)
    {
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        startPage();
        List<JSONObject> list = learnTeacherService.getPapers(req, SysUser.isAdmin(userId)?null:userId);
        return getDataTable(list);
    }

    @GetMapping("/getPaperStudentRecords")
    @ApiOperation("班级详情")
    public AjaxResult getPaperStudentRecords(TestPaperVO.TestPaperBuildReq req)
    {
        List<JSONObject> list = learnTeacherService.getPaperStudentRecords(req);
        list.stream().forEach(o -> {
            Integer state = o.getInteger("state");
            o.put("state", PaperBuildStatus.of(state).getTitle());
        });
        return AjaxResult.success(list);
    }

    @GetMapping("/getPaperStudentDetail")
    @ApiOperation("学生详情")
    public AjaxResult getPaperStudentDetail(@ApiParam("考卷ID") Long examineeId)
    {
        return AjaxResult.success(learnTeacherService.getPaperStudentDetail(examineeId));
    }

    @PostMapping("/postUnfinishAlarm")
    @ApiOperation("学生提醒")
    public AjaxResult postUnfinishAlarm(@ApiParam("组卷类型") String buildType, @ApiParam("批次") Long batchId, @ApiParam("班级") Long classId)
    {
        return AjaxResult.success();
    }


    @GetMapping("/questionTypes")
    @ApiOperation("题型列表")
    public AjaxResult questionTypes(@ApiParam("科目ID") Long subjectId, @RequestParam(required = false) @ApiParam("知识点") Collection<Long> knowledgeIds)
    {
        List<Dict> dictList = learnTeacherService.getQuestionTypes(subjectId, knowledgeIds).stream().map(t -> {
            QuestionType qt = QuestionType.of(t.getQtpye());
            return Dict.create().set("dictLabel", qt.getTitle()).set("dictValue", qt.getVal());
        }).sorted(new Comparator<Dict>() {
            @Override
            public int compare(Dict o1, Dict o2) {
                return o1.getInt("dictValue").compareTo(o2.getInt("dictValue"));
            }
        }).collect(Collectors.collectingAndThen(
            Collectors.toMap(
                dict -> dict.getInt("dictValue"),
                dict -> dict,
                (existing, replacement) -> existing,
                LinkedHashMap::new
            ),
            map -> new ArrayList<>(map.values())
        ));
        return AjaxResult.success(dictList);
    }

    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
    @PostMapping("/build/exactIntelligent")
    @ApiOperation("定向智能")
    public AjaxResult buildExactIntelligent(@RequestBody TestPaperVO.TestPaperBuildReq req)
    {
        req.setBuildType("ExactIntelligent");
        req.setDirectType(true);
        req.setSubjectId(11L);
        req.setTeacherId(getTeacherId());
        return AjaxResult.success(learnTeacherService.buildPapersDirect(req));
    }

    private Long getTeacherId() {
        return SecurityUtils.getLoginUser().getUser().getUserTypeId();
    }

    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
    @PostMapping("/build/fullIntelligent")
    @ApiOperation("全量智能")
    public AjaxResult buildFullIntelligent(@RequestBody TestPaperVO.TestPaperBuildReq req)
    {
        req.setBuildType("FullIntelligent");
        req.setDirectType(false);
        if(null == req.getSubjectId()) {
//            AjaxResult.error("未选择科目");
            req.setSubjectId(11L);
        }
        req.setTeacherId(getTeacherId());
        return AjaxResult.success(learnTeacherService.buildPapersFull(req));
    }

    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
    @PostMapping("/build/exactHand")
    @ApiOperation("定向手动")
    public AjaxResult buildExactHand(@RequestBody TestPaperVO.TestPaperBuildReq req)
    {
        req.setBuildType("ExactHand");
        req.setDirectType(true);
        req.setSubjectId(11L);
        if(null == req.getMajorPlanId()) {
            AjaxResult.error("未选择计划");
        }
        req.setTeacherId(getTeacherId());
        return AjaxResult.success(learnTeacherService.buildPapersDirect(req));
    }

    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
    @PostMapping("/build/fullHand")
    @ApiOperation("全量手动")
    public AjaxResult buildFullHand(@RequestBody TestPaperVO.TestPaperBuildReq req)
    {
        req.setBuildType("FullHand");
        req.setDirectType(false);
        if(null == req.getSubjectId()) {
            return AjaxResult.error("未选择科目");
        }
        req.setTeacherId(getTeacherId());
        return AjaxResult.success(learnTeacherService.buildPapersFull(req));
    }

    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
    @PostMapping("/build/fullKnowledgeIntelligent")
    @ApiOperation("全量知识点智能")
    public AjaxResult buildFullKnowledgeIntelligent(@RequestBody TestPaperVO.TestPaperBuildReq req)
    {
        req.setBuildType("FullIntelligent");
        req.setDirectType(false);
        if(null == req.getSubjectId()) {
            req.setSubjectId(11L);
//            return AjaxResult.error("未选择科目");
        }
        req.setTeacherId(getTeacherId());
        return AjaxResult.success(learnTeacherService.buildPapersFullByKnowledge(req));
    }

    @PreAuthorize("@ss.hasPermi('learn:test_paper:send')")
    @GetMapping("/build/sendPaper")
    @ApiOperation("发送试卷")
    public AjaxResult sendPaper(@RequestParam("paperId") Long testPaperId, @RequestParam(value = "cardIds", required = false) String cardIdsStr)
    {
        if (testPaperId == null) {
            return AjaxResult.error("试卷ID不能为空");
        }

        // 解析 cardIds 字符串为 List<Long>
        List<Long> cardIds = new java.util.ArrayList<>();
        if (cardIdsStr != null && !cardIdsStr.isEmpty()) {
            cardIds = Arrays.stream(cardIdsStr.split(","))
                    .map(String::trim)
                    .filter(cardId -> !cardId.isEmpty())
                    .map(cardId -> {
                        try {
                            return Long.parseLong(cardId);
                        } catch (NumberFormatException e) {
                            return null;
                        }
                    })
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        }

        // Service 方法接收的是 testPaperId（learn_test_paper.id），不是 paperId
        return AjaxResult.success(learnTeacherService.sendPaper(testPaperId, cardIds));
    }

    @GetMapping("/universities")
    @ApiOperation("院校列表")
    public AjaxResult universities(@ApiParam("批次ID") Long batchId, @RequestParam @ApiParam("考生类型") ExamType examType)
    {
        SysUser sysUser = VistorContextHolder.getContext();
        return AjaxResult.success(learnTeacherService.selectUniversityList(getTeacherId(), batchId, null == examType ? sysUser.getExamType().name() : examType.name()));
    }

    @GetMapping("/majors")
    @ApiOperation("专业列表")
    public AjaxResult majors(@ApiParam("批次ID") Long batchId, @RequestParam @ApiParam("院校列表") Long universityId, @RequestParam @ApiParam("考生类型") ExamType examType)
    {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        DzControl control = dzControlService.selectDzControl(sysUser.getLocation(), examType);
        return AjaxResult.success(learnTeacherService.selectMajorList(sysUser.getUserTypeId(), universityId, control.getPlanYear(), batchId, examType.name()));
    }


    /**
     -- 1. 查询考试批次(假设每个老师自已控制)
     -- 2. 查询班老师班级列表
     -- 3. 查询定向院校列表
     -- 5. 查询定向院校专业组
     -- 6. 查询科目(分是否定向)
     -- 7. 查询知识点(分是否定向)
     -- 8. 查询单个定向时知识点树
     -- 9. 设置题型数量(预置题型要求，或人工指定，不指定时平均分配， 题型是针对院校的)
     */


    @GetMapping(value = "provinces")
    @Anonymous
    @ApiOperation("省份列表")
    public AjaxResult provinces()
    {
        DzControl cond = new DzControl();
        cond.setIsValid(1);
        return AjaxResult.success(dzControlService.selectDzControlList(cond).stream().map(t -> {
            JSONObject o = new JSONObject();
            o.put("dictValue", t.getLocation());
            o.put("dictLabel", t.getLocation());
            return o;
        }).collect(Collectors.toList()));
    }

    @GetMapping("/classes")
    @ApiOperation("2. 班级列表")
    public AjaxResult classes()
    {
        return AjaxResult.success(learnTeacherService.getClasses(getTeacherId()));
    }

    @GetMapping("/students")
    @ApiOperation("学生列表")
    public AjaxResult students(@ApiParam("批次ID") Long batchId, @ApiParam("班级ID") Long classId)
    {
        return AjaxResult.success(learnTeacherService.getStudents(batchId, classId));
    }

    @ApiOperation("04 取试卷列表")
    @GetMapping(value = "papers")
    public AjaxResult papers(@ApiParam("批次") @RequestParam(required = false) Integer batchId) {
        LearnTestPaper tpCond = new LearnTestPaper();
        tpCond.setCreatorId(getTeacherId());
        tpCond.setBatchId(batchId);
        List<LearnTestPaper> testPaperList = testPaperService.selectLearnTestPaperList(tpCond);
        List<LearnPaper> paperList = Lists.newArrayList();
        for(LearnTestPaper tp : testPaperList) {
            paperList.add(learnPaperService.selectLearnPaperById(tp.getPaperId()));
        }
        return AjaxResult.success(paperList);
    }
}
