package com.yinlihupo.enlish.service.controller;


import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsDO;
import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsJudgeResultDO;
import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO;
import com.yinlihupo.enlish.service.model.bo.StudentDetail;
import com.yinlihupo.enlish.service.model.bo.Word;
import com.yinlihupo.enlish.service.model.vo.exam.*;
import com.yinlihupo.enlish.service.service.ExamWordsJudgeService;
import com.yinlihupo.enlish.service.service.ExamWordsService;
import com.yinlihupo.enlish.service.service.StudentService;
import com.yinlihupo.enlish.service.service.VocabularyService;
import com.yinlihupo.enlish.service.utils.WordExportUtil;
import com.yinlihupo.framework.biz.operationlog.aspect.ApiOperationLog;
import com.yinlihupo.framework.common.response.PageResponse;
import com.yinlihupo.framework.common.response.Response;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

@RequestMapping("/exam/words/")
@RestController
@Slf4j
public class ExamWordsController {

    @Resource
    private ExamWordsService examWordsService;
    @Resource
    private VocabularyService vocabularyService;
    @Value("${templates.word}")
    private String templateWordPath;
    @Resource
    private ExamWordsJudgeService examWordsJudgeService;
    @Resource
    private StudentService studentService;

    @PostMapping("generate")
    public void generateFeltExamWords(@RequestBody GenerateExamWordsReqVO generateExamWordsReqVO, HttpServletResponse response) {
        Integer type = generateExamWordsReqVO.getType();
        Integer studentId = generateExamWordsReqVO.getStudentId();
        if (studentId == null) {
            throw new RuntimeException("参数错误");
        }
        try {
            ExamWordsDO examWordsDO = examWordsService.generateExamWords(studentId, type);
            if (examWordsDO == null || examWordsDO.getWordIds().isEmpty()) {
                throw new RuntimeException("没有单词");
            }

            List<VocabularyBankDO> vocabularyBankDOS = vocabularyService.findVocabularyBankDOListById(examWordsDO.getWordIds());
            List<Word> assessmentWords = vocabularyBankDOS.stream().map(vocabularyBankDO -> Word.builder()
                    .id(vocabularyBankDO.getId())
                    .title(vocabularyBankDO.getWord())
                    .definition(vocabularyBankDO.getDefinition().length() > 6 ? vocabularyBankDO.getDefinition().substring(0, 6) : vocabularyBankDO.getDefinition())
                    .build()).toList();
            // bug: 获取单词后，单词的id会乱序、 需要重新更新考试记录中的 id
            examWordsDO.setWordIds(assessmentWords.stream().map(Word::getId).toList());
            examWordsService.updateExamWordsWordIdsOrder(examWordsDO);

            List<StudentDetail> studentDetailList = studentService.getStudentDetailList(Collections.singletonList(studentId));
            List<Map<String, Object>> maps = studentDetailList.stream().map(studentDetail -> {
                Map<String, Object> data = new HashMap<>();
                data.put("examId", examWordsDO.getId());
                data.put("studentId", studentDetail.getId());
                data.put("studentStr", studentDetail.getName() + studentDetail.getClassName() + studentDetail.getGradeName());
                data.put("examStr", examWordsDO.getTitle());
                data.put("words", assessmentWords);
                data.put("answer", assessmentWords);

                List<Word> words1 = assessmentWords.subList(0, assessmentWords.size() / 2);
                List<Word> words2 = assessmentWords.subList(assessmentWords.size() / 2, assessmentWords.size());
                data.put("words1", words1);
                data.put("words2", words2);

                return data;
            }).toList();

            WordExportUtil.generateExamWords(maps, examWordsDO, response, templateWordPath);

        } catch (Exception e) {

            if (!response.isCommitted()) {
                response.reset();
                response.setContentType("application/json;charset=UTF-8");
                throw new RuntimeException("生成试卷失败: " + e.getMessage());
            } else {
                throw new RuntimeException("生成试卷导出中断", e);
            }
        }
    }

    @PostMapping("submit")
    public Response<String> submitExamWords(@RequestParam("file") MultipartFile file) {
        try {
            int saveExamWordsPngToDbAndLocal = examWordsService.saveExamWordsPngToDbAndLocal(file);
            if (saveExamWordsPngToDbAndLocal > 0) {
                return Response.success("保存成功");
            }
            return Response.fail("保存失败");
        } catch (Exception e) {
            return Response.fail("保存失败: " + e.getMessage());
        }
    }

    @PostMapping("get")
    @ApiOperationLog(description = "获取试卷结果集合")
    PageResponse<ExamWordsResultRspVO> getExamWordsResult(@RequestBody ExamWordsResultReqVO examWordsResultReqVO) {
        Integer page = examWordsResultReqVO.getPage();
        Integer size = examWordsResultReqVO.getSize();
        Integer classId = examWordsResultReqVO.getClassId();
        Integer gradeId = examWordsResultReqVO.getGradeId();
        String studentName = examWordsResultReqVO.getStudentName();
        Integer total = examWordsJudgeService.getExamWordsJudgeResultCount();
        List<ExamWordsJudgeResultDO> examWordsJudgeResult = examWordsJudgeService.getExamWordsJudgeResult(page, size, classId, gradeId, studentName);
        List<ExamWordsResultRspVO> list = examWordsJudgeResult.stream().map(examWordsJudgeResultDO -> ExamWordsResultRspVO
                .builder()
                .id(examWordsJudgeResultDO.getId())
                .studentId(examWordsJudgeResultDO.getStudentId())
                .studentName(examWordsJudgeResultDO.getStudentId() != null ? studentService.getStudentById(examWordsJudgeResultDO.getStudentId()).getName() : "")
                .examWordsTitle(examWordsJudgeResultDO.getExamWordsId() != null ? examWordsService.getExamWordsDOById(examWordsJudgeResultDO.getExamWordsId()).getTitle() : "")
                .examWordsId(examWordsJudgeResultDO.getExamWordsId())
                .startDate(examWordsJudgeResultDO.getStartDate())
                .correctWordCount(examWordsJudgeResultDO.getCorrectWordCount())
                .wrongWordCount(examWordsJudgeResultDO.getWrongWordCount())
                .isFinished(examWordsJudgeResultDO.getIsFinished())
                .msg(examWordsJudgeResultDO.getMsg())
                .build()
        ).toList();
        return PageResponse.success(list, page, total, size);
    }

    @PostMapping("detail")
    @ApiOperationLog(description = "获取试卷结果详情")
    Response<ExamWordsDetailResultRspVO> getExamWordsResultDetail(@RequestBody ExamWordsDetailResultReqVO examWordsDetailResultReqVO) {
        Integer id = examWordsDetailResultReqVO.getId();
        ExamWordsJudgeResultDO examWordsJudgeResultDO = examWordsJudgeService.getExamWordsJudgeResultDOById(id);
        ExamWordsDetailResultRspVO examWordsDetailResultRspVO = ExamWordsDetailResultRspVO.builder()
                .id(id)
                .studentId(examWordsJudgeResultDO.getStudentId())
                .examWordsId(examWordsJudgeResultDO.getExamWordsId())
                .startDate(examWordsJudgeResultDO.getStartDate())
                .correctWordCount(examWordsJudgeResultDO.getCorrectWordCount())
                .wrongWordCount(examWordsJudgeResultDO.getWrongWordCount())
                .isFinished(examWordsJudgeResultDO.getIsFinished())
                .errorMsg(examWordsJudgeResultDO.getMsg())
                .correctWordIds(examWordsJudgeResultDO.getCorrectWordIds())
                .wrongWordIds(examWordsJudgeResultDO.getWrongWordIds())
                .build();

        return Response.success(examWordsDetailResultRspVO);
    }

    @PostMapping("student/history")
    @ApiOperationLog(description = "获取学生历史考试结果")
    Response<List<FindStudentExamWordsResultListRspVO>> getStudentExamWordsResultList(@RequestBody FindStudentExamWordsResultReqVO findStudentExamWordsResultReqVO) {
        Integer studentId = findStudentExamWordsResultReqVO.getStudentId();
        List<FindStudentExamWordsResultListRspVO> list = examWordsJudgeService.getStudentExamWordsResultList(studentId).stream().map(examWordsJudgeResultDO -> FindStudentExamWordsResultListRspVO.builder()
                .id(examWordsJudgeResultDO.getId())
                .studentId(examWordsJudgeResultDO.getStudentId())
                .examWordsId(examWordsJudgeResultDO.getExamWordsId())
                .correctWordCount(examWordsJudgeResultDO.getCorrectWordCount())
                .wrongWordCount(examWordsJudgeResultDO.getWrongWordCount())
                .startDate(examWordsJudgeResultDO.getStartDate())
                .accuracy((double)examWordsJudgeResultDO.getCorrectWordCount() / (examWordsJudgeResultDO.getCorrectWordCount() + examWordsJudgeResultDO.getWrongWordCount()))
                .build()
        ).toList();

        return Response.success(list);
    }
}
