package jnpf.cultivate.v2.controller.web.question;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import jnpf.base.ActionResult;
import jnpf.base.vo.DownloadVO;
import jnpf.cultivate.utils.QuestionExcelExportUtil;
import jnpf.cultivate.v2.service.V2CultivateQuestionService;
import jnpf.cultivate.v2.util.V2QuestionExcelExportUtil;
import jnpf.model.cultivate.req.paper.PreQuestionImportReq;
import jnpf.model.cultivate.req.questionbank.QuestionOptionReq;
import jnpf.model.cultivate.resp.ExcelUserQuestionVo;
import jnpf.model.cultivate.resp.PreQuestionImportVO;
import jnpf.model.cultivate.resp.QuestionVo;
import jnpf.model.cultivate.v2.question.req.*;
import jnpf.model.enums.CourseEnums;
import jnpf.util.RedisUtil;
import jnpf.util.excel.EasyExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * web题目模块
 *
 * @author xgl
 */
@Slf4j
@RestController
@RequestMapping("/v2/web/question")
public class V2CultivateQuestionController {

    @Autowired
    private V2CultivateQuestionService questionService;


    @Autowired
    private RedisUtil redisUtil;

    /**
     * 批量添加问题的接口方法。
     *
     * @param req 包含批量添加问题请求数据的对象，必须通过@Valid注解进行校验
     * @return 返回一个ActionResult对象，其中包含操作结果（true表示成功）
     */
    @PostMapping("/batch-add")
    public ActionResult<Boolean> batchAddQuestion(@RequestBody @Valid BatchAddQuestionReq req) throws Exception {
        // 调用questionService的batchAddQuestion方法执行批量添加逻辑
        questionService.batchAddQuestion(req);
        // 返回操作成功的ActionResult对象
        return ActionResult.success(true);
    }

    /**
     * 编辑题目
     *
     * @param editQuestion
     * @return
     */
    @PostMapping("/edit")
    public ActionResult<Boolean> editQuestion(@RequestBody @Valid V2EditQuestionReq editQuestion) throws Exception {
        V2QuestionExcelExportUtil.checkEditQuestionParam(editQuestion);
        questionService.updateData(editQuestion);
        return ActionResult.success(true);
    }


    /**
     * 查询题目详情，编辑时使用
     *
     * @param id 题目ID
     * @return
     */
    @GetMapping("/get/{id}")
    public ActionResult<QuestionVo> get(@PathVariable("id") String id) {
        return ActionResult.success(questionService.getInfo(id));
    }


    /**
     * 预检测题目导入接口
     *
     * @param preQuestionImportReq
     * @param questionBankId       题库ID
     * @return
     */
    @PostMapping("/preImportData/{questionBankId}")
    public ActionResult<V2PreQuestionImportVO> preImportData(@RequestBody @Validated PreQuestionImportReq preQuestionImportReq, @PathVariable(name = "questionBankId") String questionBankId) {
        String rediskey = QuestionExcelExportUtil.qeneralQuestionImportKey();
        redisUtil.remove(rediskey);
        ImportParams importParams = new ImportParams();
        importParams.setStartSheetIndex(1); // 读取第二个Sheet，因为索引是从0开始
        List<V2ExcelImportQuestionResultReq> allQuestionList = new ArrayList<>();
        try {
            InputStream inputStream = EasyExcelUtils.checkExcelFile(preQuestionImportReq.getFileUrl());
            List<Map<String, Object>> list = ExcelImportUtil.importExcel(inputStream, Map.class, importParams);
            log.info("题库导入数据：{}", JSON.toJSONString(list));
            inputStream.close();

            int line = 2;
            for (Map<String, Object> o : list) {
                V2ExcelImportQuestionResultReq addQuestionReq = new V2ExcelImportQuestionResultReq();
                CourseEnums.QuestionType type = CourseEnums.QuestionType.getByDesc(String.valueOf(o.get("题型")));
                CourseEnums.QuestionDifficulty difficulty = CourseEnums.QuestionDifficulty.getByDesc(String.valueOf(o.get("难度")));
                addQuestionReq.setContent(ObjectUtils.isNotEmpty(o.get("题目")) ? String.valueOf(o.get("题目")) : "");
                addQuestionReq.setAnalysis(ObjectUtils.isNotEmpty(o.get("解析")) ? String.valueOf(o.get("解析")) : "");
                if (null == difficulty || null == type || StringUtils.isEmpty(addQuestionReq.getContent())) {
                    addQuestionReq.setMsg("题目内容为空");
                    addQuestionReq.setSuccess(1);
                    continue;
                }
                addQuestionReq.setDifficulty(difficulty.getCode());
                addQuestionReq.setType(type.getCode());
                List<QuestionOptionReq> optionFormList = new ArrayList<>();

                Set<String> keySet = o.keySet();
                long sortCode = 0;
                String answer = "";
                for (String key : keySet) {
                    QuestionOptionReq optionForm = new QuestionOptionReq();
                    if (key.contains("选项")) {
                        answer = String.valueOf(o.get("正确答案"));
                        String option = key.substring(2);
                        if (Objects.isNull(o.get(key))) {
                            continue;
                        }
                        optionForm.setContent(String.valueOf(o.get(key)));
                        if (!StringUtils.isEmpty(answer)) {
                            optionForm.setIsRightOption(answer.contains(option) ? 1 : 0);
                        }
                        optionForm.setSortCode(sortCode++);
                        optionFormList.add(optionForm);
                    }
                    if (CourseEnums.QuestionType.FILL.getCode().equals(addQuestionReq.getType())) {
                        optionForm.setRightAnswer(optionForm.getContent());
                    }
                }
                addQuestionReq.setOptionList(optionFormList);
                if (addQuestionReq.getType().equals(CourseEnums.QuestionType.INPUT.getCode())) {
                    addQuestionReq.setAnswer(answer);
                }
                allQuestionList.add(addQuestionReq);
                line++;
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("题目与导入失败");
            return ActionResult.fail("文件解析异常，导入失败!");
        }
        //
        if (CollUtil.isEmpty(allQuestionList)) {
            throw new RuntimeException("导入题列表不能为空");
        }
        V2QuestionExcelExportUtil.dealFillQuestion(allQuestionList);
        V2PreQuestionImportVO vo = new V2PreQuestionImportVO();
        vo.setUniqueId(rediskey);

        List<V2ExcelImportQuestionResultReq> normal = new ArrayList<>();
        List<V2ExcelImportQuestionResultReq> error = new ArrayList<>();
        for (V2ExcelImportQuestionResultReq item : allQuestionList) {
            if (item.getSuccess() == 1) {//fail
                error.add(item);
            } else {//success
                normal.add(item);
            }
        }
        vo.setNormal(normal);
        vo.setError(error);
        vo.setNormalNumber(normal.size());
        vo.setErrorNumber(error.size());
        redisUtil.insert(rediskey, vo, 60 * 60);
        return ActionResult.success("成功", vo);

    }


    /**
     * 真正导入题目到题库
     *
     * @param questionBankId 题库ID
     * @param key            预检测导入时返回的唯一标识(必传)，用于导出异常数据
     * @return
     */
    @PostMapping("/realImportData/{questionBankId}/{key}")
    public ActionResult<Object> realImportData(@PathVariable(name = "questionBankId") String questionBankId, @PathVariable(name = "key") String key) {
        if (!redisUtil.exists(key)) {
            throw new RuntimeException("导入数据已过期，请重新导入!");
        }
        V2PreQuestionImportVO data = JSON.parseObject(redisUtil.getString(key).toString(), V2PreQuestionImportVO.class);
        if (data == null || CollUtil.isEmpty(data.getNormal())) {
            throw new RuntimeException("无正常题目可以导入");
        }
        V2ImportQuestionResultVo importQuestionResultVo = questionService.realImportData(questionBankId, data.getNormal());
        if (CollUtil.isEmpty(importQuestionResultVo.getFailList())) {
            String rediskey = V2QuestionExcelExportUtil.qeneralQuestionImportKey();
            redisUtil.remove(rediskey);
        }
        return ActionResult.success("导入成功", importQuestionResultVo);
    }

    /**
     * 异常数据导出
     *
     * @param key 预检测导入时返回的唯一标识(必传)，用于导出异常数据
     */
    @GetMapping("/exceptionDataExport/{key}")
    public void exceptionDataExport(@PathVariable(name = "key") String key, HttpServletResponse response) throws IOException {
        if (!redisUtil.exists(key)) {
            throw new RuntimeException("导入数据已过期，请重新导入!");
        }
        PreQuestionImportVO data = JSON.parseObject(redisUtil.getString(key).toString(), PreQuestionImportVO.class);
        String fileName = "异常题目" + DateUtil.format(new Date(), "yyyyMMdd");
        if (data.getErrorNumber() <= 0) {
            throw new RuntimeException("无异常数据");
        }
        List<ExcelUserQuestionVo> list = QuestionExcelExportUtil.convertErrorQuestionList(data.getError());
        QuestionExcelExportUtil.questionExportExcel(response, fileName, list, ExcelUserQuestionVo.class);
    }


    /**
     * 模版下载
     *
     * @return 模版下载信息
     */
    @GetMapping("/download/template")
    public ActionResult<DownloadVO> templateDownload() {
        DownloadVO vo = DownloadVO.builder().build();
        try {
            vo.setName("题目导入模板.xlsx");
            vo.setUrl("https://jnpf-resource-1304460613.cos.ap-chengdu.myqcloud.com/jnpf-resources/v2/face/xlsx/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BFV2.xlsx");
        } catch (Exception e) {
            log.error("下载模板错误:" + e.getMessage());
        }
        return ActionResult.success(vo);
    }
}
