package com.ynfy.buss.exam.question.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ynfy.buss.exam.paper.enmus.JoinType;
import com.ynfy.buss.exam.paperquestion.service.IPaperQuestionService;
import com.ynfy.buss.exam.paperruledetail.dto.RuleDetailDTO;
import com.ynfy.buss.exam.paperruledetail.entity.PaperRuleDetail;
import com.ynfy.buss.exam.question.dto.QuestionDTO;
import com.ynfy.buss.exam.question.entity.Question;
import com.ynfy.buss.exam.question.service.IQuestionService;
import com.ynfy.buss.exam.questionanswer.entity.QuestionAnswer;
import com.ynfy.buss.exam.questionanswer.service.IQuestionAnswerService;
import com.ynfy.buss.exam.userexamquestion.service.IUserExamQuestionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: question
 * @Author: jeecg-boot
 * @Date: 2023-02-22
 * @Version: V1.0
 */
@Api(tags = "题目")
@RestController
@RequestMapping("/question")
@Slf4j
public class QuestionController extends JeecgController<Question, IQuestionService> {
    @Autowired
    private IQuestionService questionService;

    @Autowired
    private IQuestionAnswerService questionAnswerService;

    @Autowired
    private IPaperQuestionService paperQuestionService;

    @Autowired
    private IUserExamQuestionService userExamQuestionService;

    /**
     * 分页列表查询
     *
     * @param question
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "题目-分页列表查询", notes = "题目-分页列表查询")
    @RequiresPermissions("question:list")
    @GetMapping(value = "/list")
    public Result<IPage<Question>> queryPageList(Question question,
                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                 HttpServletRequest req) {
        Page<Question> page = new Page<Question>(pageNo, pageSize);
        IPage<Question> pageList = questionService.selectPageList(page, question);
        return Result.OK(pageList);
    }

    /**
     * 保存
     *
     * @return
     */
    @ApiOperation(value = "题目-保存")
    @RequiresPermissions("question:save")
    @RequestMapping(value = "/save", method = {RequestMethod.POST})
    public Result<String> save(@RequestBody Question question) {
        questionService.saveQuestion(question);
        return Result.OK("保存成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "题目-通过id删除")
    @ApiOperation(value = "题目-通过id删除", notes = "题目-通过id删除")
    @RequiresPermissions("question:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        questionService.removeQuestionAnswer(id);
        return Result.OK("删除成功!");
    }

    /**
     * 导入题目
     *
     * @return
     */
    @ApiOperation(value = "题目-导入题目")
    @RequiresPermissions("question:import")
    @RequestMapping(value = "/importExcel", method = {RequestMethod.POST})
    public Result<String> importExcel(MultipartFile file) throws Exception {
        questionService.importExcel(file);
        return Result.OK("导入题目成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "题目-批量删除")
    @ApiOperation(value = "题目-批量删除", notes = "题目-批量删除")
    @RequiresPermissions("question:delete")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.questionService.removeBatch(ids);
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "题目-通过id查询", notes = "题目-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        Question question = questionService.getById(id);
        if (question == null) {
            return Result.error("未找到对应数据");
        }
        List<QuestionAnswer> answers = questionAnswerService.listAnswerByQuestionId(id);
        question.setAnswerList(answers);
        return Result.OK(question);
    }


    /**
     * 下载导入模板
     */
    @ApiOperation(value = "题目-下载导入模板", notes = "题目-下载导入模板")
    @RequiresPermissions("question:downloadTemplate")
    @GetMapping(value = "/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) throws Exception {
        questionService.downloadTemplate(response);
    }

    /**
     * 列表查询
     *
     * @param question
     * @param pageNo
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "题目-列表查询", notes = "题目-列表查询")
    @GetMapping(value = "/queryPageList")
    public Result<IPage<Question>> queryList(Question question,
                                             @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                             @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                             HttpServletRequest req, String excludeQIds) {
        QueryWrapper<Question> queryWrapper = QueryGenerator.initQueryWrapper(question, req.getParameterMap());
        if (StringUtils.isNotBlank(excludeQIds)) {
            queryWrapper.notIn("id", Arrays.asList(excludeQIds.split(",")));
        }
        Page<Question> page = new Page<>(pageNo, pageSize);
        IPage<Question> pageList = questionService.page(page, queryWrapper);
        if (!Objects.isNull(pageList)) {
            List<Question> records = pageList.getRecords();
            if (!CollectionUtils.isEmpty(records)) {
                List<String> idList = records.stream().map(Question::getId).collect(Collectors.toList());
                List<Question> questionList = questionService.selectQuestionList(idList, true, false);
                pageList.setRecords(questionList);
            }
        }
        return Result.OK(pageList);
    }

    /**
     * 按照难度分组查询
     *
     * @return
     */
    @ApiOperation(value = "题目-按照难度分组查询", notes = "题目-按照难度分组查询")
    @PostMapping(value = "/groupLevelById")
    public Result<List<QuestionDTO>> groupLevelById(@RequestBody RuleDetailDTO dto) {
        if (StringUtils.isBlank(dto.getRepositoryIds())) {
            return Result.OK();
        }
        if (Objects.isNull(dto.getJoinType())) {
            throw new JeecgBootException("组卷方式不能为空");
        }
        List<QuestionDTO> questionDTOs = null;
        if (JoinType.SJ.getCode().equals(dto.getJoinType())) {//随机组卷
            questionDTOs = questionService.groupLevelById(Arrays.asList(dto.getRepositoryIds().split(",")), dto.getType(), null);
            if (!StringUtils.isEmpty(dto.getRuleList())) {
                List<PaperRuleDetail> ruleDetails = JSONObject.parseArray(JSON.toJSON(dto.getRuleList()).toString(), PaperRuleDetail.class);
                if (!CollectionUtils.isEmpty(ruleDetails)) {
                    for (PaperRuleDetail rule : ruleDetails) {
                        for (QuestionDTO tmp : questionDTOs) {
                            if (tmp.getRepositoryId().equals(rule.getRepositoryId()) && tmp.getType().equals(dto.getType())
                                    && tmp.getLevel().equals(rule.getLevel())) {
                                tmp.setNum(rule.getNum());
                                break;
                            }
                        }
                    }
                }
            }
        } else if (JoinType.CT.getCode().equals(dto.getJoinType())) {//抽题组卷
            questionDTOs = questionService.groupLevelById(Arrays.asList(dto.getRepositoryIds().split(",")),
                    dto.getType(), StringUtils.isNotBlank(dto.getQuestionIds()) ? Arrays.asList(dto.getQuestionIds().split(",")) : null);
        }
        return Result.OK(questionDTOs);
    }

    /**
     * 检查题目是否已经被试卷使用
     *
     * @param questionIds
     * @return
     */
    @ApiOperation(value = "题目-检查题目是否已经被试卷使用", notes = "题目-检查题目是否已经被试卷使用")
    @GetMapping(value = "/checkIsUsed")
    public Result<?> checkIsUsed(@RequestParam(name = "questionIds", required = true) String questionIds) {
        return Result.OK(paperQuestionService.checkIsUsed(questionIds.split(",")));
    }

    /**
     * 检查题目是否已经被考试
     *
     * @param questionIds
     * @return
     */
    @ApiOperation(value = "题目-检查题目是否已经被考试", notes = "题目-检查题目是否已经被考试")
    @GetMapping(value = "/checkIsUsedInExam")
    public Result<?> checkIsUsedInExam(@RequestParam(name = "questionIds", required = true) String questionIds) {
        return Result.OK(userExamQuestionService.checkIsUsedInExam(questionIds.split(",")));
    }

    /**
     * 按练习模式获取指定题库题目
     *
     * @return
     */
    @ApiOperation(value = "按练习模式获取指定题库题目", notes = "按练习模式获取指定题库题目")
    @GetMapping(value = "/listQuestionByMode")
    public Result<?> listQuestionByPracticeMode(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                @RequestParam String repositoryId, Integer questionType, @RequestParam Integer mode) {
        return Result.OK(questionService.listQuestionByPracticeMode(pageNo, pageSize, repositoryId, questionType, mode));
    }

    /**
     * 护理三基excel题目导入
     *
     * @return
     */
    @ApiOperation(value = "护理三基excel题目导入")
    @RequestMapping(value = "/castExcel", method = {RequestMethod.POST})
    public Result<String> castExcel(MultipartFile file) throws Exception {
        questionService.castExcel(file);
        return Result.OK("护理三基excel题目导入成功!");
    }

}
