package com.ruoyi.web.controller.front;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.dz.service.IDzControlService;
import com.ruoyi.enums.ExamineeStatus;
import com.ruoyi.enums.PaperType;
import com.ruoyi.ie.domain.AMarjorPlan;
import com.ruoyi.ie.service.IAMarjorPlanService;
import com.ruoyi.learn.domain.LearnExaminee;
import com.ruoyi.learn.domain.LearnPaper;
import com.ruoyi.learn.service.ILearnExamineeService;
import com.ruoyi.learn.service.ILearnPaperService;
import com.ruoyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.ValidationException;
import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("/front/exam")
@Api(tags = "前台-学习-考试练习")
public class FrontExamController {
    private Set<PaperType> paperTypeSet = Sets.newHashSet(PaperType.Real, PaperType.Custom, PaperType.Test);
    private final IDzControlService controlService;
    private final ISysUserService sysUserService;
    private final ILearnPaperService paperService;
    private final ILearnExamineeService examineeService;
    private final IAMarjorPlanService marjorPlanService;

    public FrontExamController(IDzControlService controlService, ISysUserService sysUserService, ILearnPaperService paperService, ILearnExamineeService examineeService, IAMarjorPlanService marjorPlanService) {
        this.controlService = controlService;
        this.sysUserService = sysUserService;
        this.paperService = paperService;
        this.examineeService = examineeService;
        this.marjorPlanService = marjorPlanService;
    }

    // 试卷: 真题卷,批次测试卷,自组卷, 生成考试记录
    // 定向模拟卷: 根据用户选择生成记录
    // 组卷: 知识点 错题 必刷题 实时组卷后才生成记录
    @ApiOperation("01 开卷")
    @GetMapping(value = "openExaminee")
    public AjaxResult openExamineePaper(@ApiParam("考卷类型PaperType") PaperType paperType,
                                        @ApiParam("考卷类型关联ID") Long relateId,
                                        @RequestBody JSONObject param) {
        LearnPaper paper = paperService.selectLearnPaperById(relateId);
        LearnExaminee examinee = new LearnExaminee();
        examinee.setStudentId(SecurityUtils.getLoginUser().getUser().getUserId());
        examinee.setPaperType(paperType.getVal());
        if(!paperTypeSet.contains(paperType)) {
            if(PaperType.Simulated.equals(paperType)) { // 检查是否超过最大值从顺序选择未做过的考卷来
                return AjaxResult.success(openSimulatedPaper(examinee, param));
            } else { // 根据几种场景实时组卷,然后返回PaperId
                return AjaxResult.success(openCustomPaper(paperType, examinee, param));
            }
        }
        examinee.setPaperKey(paperType.name() + "_" + paper.getId());
        return AjaxResult.success(newExamineePcondaper(examinee, paper, param));
    }

    private LearnExaminee newExamineePcondaper(LearnExaminee examinee, LearnPaper paper, JSONObject param) {
        examinee.setPaperId(paper.getId());
        examinee.setParams(param);
        examinee.setState(ExamineeStatus.Exam.getVal());
        examinee.setBeginTime(DateUtils.getNowDate());
        examineeService.insertLearnExaminee(examinee);
        return examinee;
    }

    private LearnExaminee openCustomPaper(PaperType paperType, LearnExaminee examinee, JSONObject param) {
        Long knowledgeId = param.getLong("knowledgeId");
        examinee.setPaperKey(paperType.name() + knowledgeId);
        examinee.setState(ExamineeStatus.Exam.getVal());
        List<LearnExaminee> examineeList = examineeService.selectLearnExamineeList(examinee);
        if(CollectionUtils.isNotEmpty(examineeList)) {
            return examineeList.get(0);
        }
        // 全局配置模板参数或知识点级的参数
        LearnPaper paper = paperService.selectLearnPaperById(0L);
        if(null == paper) {
            throw new ValidationException("未组卷");
        }
        return newExamineePcondaper(examinee, paper, param);
    }

    private LearnExaminee openSimulatedPaper(LearnExaminee examinee, JSONObject param) {
        List<LearnExaminee> examineeList = examineeService.selectLearnExamineeList(examinee);
        Set<Long> existPaperIdSet = Sets.newHashSet();
        for(LearnExaminee e : examineeList) {
            if(ExamineeStatus.Exam.getVal().equals(e.getState())) {
                return e;
            }
            existPaperIdSet.add(e.getPaperId());
        }
        Long id = param.getLong("id");
        AMarjorPlan plan = marjorPlanService.selectAMarjorPlanById(id);
        if(null == plan) {
            throw new ValidationException("专业id无效");
        }
        LearnPaper paper = getBestPaper(plan, existPaperIdSet);
        examinee.setPaperKey(PaperType.Simulated.name() + "_" + paper.getId());
        return newExamineePcondaper(examinee, paper, param);
    }

    private LearnPaper getBestPaper(AMarjorPlan plan, Set<Long> existPaperIdSet) {
        String groupName = StringUtils.trimToEmpty(plan.getMajorGroup());
        LearnPaper paperCond = new LearnPaper();
        paperCond.setPaperType(PaperType.Simulated.name());
        for(int i = 3; i>0; i--) {
            if(i == 3) {
                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName + "_" + plan.getMajorName());
            } else if(i == 2) {
                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName);
            } else if(StringUtils.isBlank(groupName)) {
                break;
            }
            List<LearnPaper> paperList = paperService.selectLearnPaperList(paperCond);
            for(LearnPaper paper : paperList) {
                if(existPaperIdSet.add(paper.getId())) {
                    return paper;
                }
            }
        }
        throw new ValidationException("未初始化院校定向模拟题库: " + plan.getId());
    }

    @ApiOperation("04 取答案")
    @GetMapping(value = "answerExaminee")
    public AjaxResult loadAnswers(@ApiParam("答卷ID") Long examineeId) {
        // 检查状态，以决定是否返回答案
        return AjaxResult.success();
    }

    /*@ApiOperation("02 答题")
    @PostMapping(value = "commitExamineeQuestion")
    public AjaxResult commitExamineeQuestion(@RequestBody PaperDto paperDto) {
        return adminExaminationService.saveQuestion(paperDto);
    }

    @ApiOperation("02 交卷")
    @PostMapping(value = "commitExamineePaper")
    public AjaxResult commitExamineePaper(@RequestBody PaperDto paperDto) {
        if (MxjbContants.ExamineeTypeIeValue.equals(paperDto.getExamineeType())) {
            return mxjbPaperExamService.saveExamPaper(paperDto);
        }
        return syTestMajorService.saveTestPaper(paperDto);
    }

    @ApiOperation("04 阅卷打分")
    @PostMapping(value = "scoreExamineeQuestions")
    public AjaxResult scoreExamineeQuestions(@RequestBody PaperDto paperDto) {
        if (MxjbContants.ExamineeTypeIeValue.equals(paperDto.getExamineeType())) {
            return mxjbPaperExamService.scoreExamineeQuestion(paperDto, true);
        }
        return AjaxResult.error("不支持: " + paperDto.getExamineeType());
    }

    @ApiOperation("05 阅卷结束")
    @PostMapping(value = "scoreFinish")
    public AjaxResult scoreFinish(
            @ApiParam("考生答卷Id") @RequestParam Long examineeId,
            @ApiParam("考生类型 1是测评evaluation(default)，2是竞赛competitor 3 ai 5 homework 6 ie") @RequestParam(required = false, defaultValue = "1") Integer examineeType) {
        if (MxjbContants.ExamineeTypeIeValue.equals(examineeType)) {
            return mxjbPaperExamService.scoreFinish(examineeId);
        }
        return AjaxResult.error("不支持： " + examineeType);
    }
    @ApiOperation("06 查看题")
    @GetMapping(value = "openQuestion")
    public QuestionDto openQuestion(@ApiParam("考生答卷Id") @RequestParam Long examineeId, @ApiParam("考生试题ID") @RequestParam Long questionId,
                                    @ApiParam("考生类型 1是测评evaluation(default)，2是竞赛competitor 3 ai 5 homework 6 ie") @RequestParam(required = false, defaultValue = "1") Integer examineeType) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (MxjbContants.ExamineeTypeIeValue.equals(examineeType)) {
            return mxjbPaperExamService.openQuestion(examineeId, loginUser.getUser().getUserId(), questionId);
        }
        return new QuestionDto();
    }
*/
}
