package cn.reghao.tnb.content.app.exam.service;

import cn.reghao.jutil.jdk.web.db.Page;
import cn.reghao.jutil.jdk.serializer.JsonConverter;
import cn.reghao.jutil.jdk.io.TextFile;
import cn.reghao.jutil.jdk.string.SnowFlake;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.content.app.ContentApplication;
import cn.reghao.tnb.content.app.exam.db.mapper.*;
import cn.reghao.tnb.content.app.exam.model.constant.QuestionType;
import cn.reghao.tnb.content.app.exam.model.dto.PaperAddDto;
import cn.reghao.tnb.content.app.exam.model.po.*;
import cn.reghao.tnb.content.app.exam.model.query.QuestionQuery;
import cn.reghao.tnb.content.app.exam.model.vo.QuestionInfo;
import cn.reghao.tnb.content.app.util.redis.ds.RedisHash;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang.StringUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2025-08-05 21:28:11
 */
@ActiveProfiles("dev")
@SpringBootTest(classes = ContentApplication.class)
public class ExamTest {
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    QuestionOptionMapper questionOptionMapper;
    @Autowired
    PaperMapper paperMapper;
    @Autowired
    PaperQuestionMapper paperQuestionMapper;
    @Autowired
    PaperAnswerMapper paperAnswerMapper;

    @Test
    public void questionTest() {
        int questionType = QuestionType.QUESTION1.getCode();
        long questionId = 1;
        String content = "";
        String extra = "";
        Question question = new Question(questionId, content, questionType, extra);

        String content1 = "";
        int pos = 1;
        boolean correct = true;
        QuestionOption questionOption = new QuestionOption(questionId, content1, pos, correct);
    }

    SnowFlake idGenerator = new SnowFlake(1L, 1L);
    @Test
    public void setQuestion6Test() {
        int questionType = QuestionType.QUESTION6.getCode();
        long questionId = idGenerator.nextId();
        String content = "阅读下面的文字，完成1—3题。   \n" +
                "\n" +
                "随着中国考古学的飞速发展，考古资料得以大量积累，考古学文化时空框架体系基本建立，多学科合作日益深入，各种专题研究广泛展开。“考古写史”在中国已经取得巨大成就，获得诸多具有突破性和填补空白意义的成绩，中国考古学证明了自身的价值，尤其是在上古史构建方面展现了广阔前景。从考古发现来看，考古学提供了传统历史学不可想象的新发现、新材料，呈现出不同时期的古代物质文化面貌、古人日常生产生活状态以及各地的文明化进程等，如不同区域新石器时代晚期大型聚落遗址、大型公共建筑、大型墓葬、水利设施、手工业作坊，以及象征王权、神权、军权和复杂礼制出现的精美玉器、陶器、漆器、象牙器等。   \n" +
                "\n" +
                "从考古发现来看，考古学提供了传统历史学不可想象的新发现、新材科，呈现出不同时期的古代物质文化面貌、古人日常生产生活状态以及各地的文明化进程等，如不同区域新石器时代晚期大型聚落遗址、大型公共建筑、大型墓葬、水利设施、手工业作坊，以及象征王权、神权、军权和复杂礼制出现的精美玉器、陶器、漆器、象牙器等。   \n" +
                "\n" +
                "从重构上古史体系角度看，20 世纪70—80年代，夏鼐、苏秉琦等系统地构建了新石器与夏商周三代时期的考古学文化区系类型时空框架体系。苏秉琦在新石器时代考古学文化区系类型基础上提出“满天星斗”“多元一体”和“古国一方国帝国”等关于中国上古史的历史叙述体系。严文明提出“重瓣花朵”模式，在承认多区域文化共存的文化多元性的同时，强调中原文化区“联系各文化区的核心作用”。张光直认为各地区文化多元发展并通过彼此之间的密切交流而形成一个“中国相互作用圈”。   \n" +
                "\n" +
                "从二里头文化、二里岗文化到殷墟考古学文化、周代考古学文化，考古学不仅展现了不同于传统文献记载的这一时期文化、科技、礼制等众多方面从发展到成熟的历史脉络，而且填补了诸多传统历史学的空白，如四川的三星堆一金沙文化、江西的吴城文化、两周时期的曾国与中山国历史，等等。   \n" +
                "\n" +
                "这些成果证明考古学完全有能力把当重写中国上古史的重任，并且已经初步形成具有自身特色的上古史叙述与解释体系，超越了传统的具有传说性质的三皇五帝体系和存在争议的夏商周三代古史体系，正如习近平总书记所说：“经过几代考古人接续奋斗，我国考古工作取得了重大成就，延伸了历史轴线，增强了历史信度，丰富了历史内涵，活化了历史场景。”   \n" +
                "\n" +
                "学界一直存在着“证经补史”的传统史学思路，试图将考古学文化体系纳入三皇五帝的古史框架体系之中，似乎中国考古学如果没有发现并证明三皇五帝与夏商周，就没有价值和意义，但研究实践告诉我们：这种传统治史思路影响了中国考古学的视野和思维方式，限制了考古学在重构中国上古史中的作用。比如，考古发现与研究显示，二里头遗址和二里头文化在东亚地区的文明形成与发展中占据了关键性地位，奠定了中国独特的礼乐文化传统的基础，在人类文明史上具有世界性的标志意义，尽管二里头遗址是否就是文献记载中的夏都所在地，在学术界仍有争议。我们对二里头遗址与二里头文化应该开展扎实的田野工作并展开全方位的考古学研究与阐释，而不是将主要目标集中于它是否是文献记载中的“夏”，并为此争论不休。\n" +
                "\n" +
                "(摘编自徐良高《以考古学构建中国上古史》)";
        String extra = "";
        Question question = new Question(questionId, content, questionType, extra);
        questionMapper.save(question);

        TextFile textFile = new TextFile();
        String filePath = "/home/reghao/Downloads/8.txt";
        List<String> list = textFile.read(filePath);

        Map<String, List<String>> map = new HashMap<>();
        List<String> lines = new ArrayList<>();
        for (String line : list) {
            if (line.isBlank()) {
                map.put(lines.get(0), lines);
                lines = new ArrayList<>();
            } else {
                lines.add(line);
            }
        }
        map.put(lines.get(0), lines);

        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
            String key = entry.getKey();
            List<String> valList = entry.getValue();

            int questionType1 = QuestionType.QUESTION1.getCode();
            long pid = question.getQuestionId();
            long questionId1 = idGenerator.nextId();
            String content1 = key;
            String extra1 = "";
            Question question1 = new Question(questionId1, content1, questionType1, extra1);
            question1.setPid(pid);
            List<QuestionOption> questionOptionList1 = new ArrayList<>();

            for (int i = 1; i < valList.size(); i++) {
                String optionContent2 = valList.get(i);
                boolean correct2 = i == valList.size()-1;
                QuestionOption questionOption2 = new QuestionOption(questionId1, optionContent2, i, correct2);
                questionOptionList1.add(questionOption2);
            }

            question1.setQuestionOptions(questionOptionList1);
            questionMapper.save(question1);
            questionOptionMapper.saveAll(questionOptionList1);
        }
    }

    @Test
    public void setQuestion5Test() {
        TextFile textFile = new TextFile();
        String filePath = "/home/reghao/Downloads/5.txt";
        List<String> list = textFile.read(filePath);

        Map<String, List<String>> map = new HashMap<>();
        List<String> lines = new ArrayList<>();
        for (String line : list) {
            if (line.startsWith("######################")) {
                map.put(lines.get(0), lines);
                lines = new ArrayList<>();
            } else {
                lines.add(line);
            }
        }
        map.put(lines.get(0), lines);

        map.values().forEach(strList -> {
            StringBuilder sb = new StringBuilder();
            for (String str : strList) {
                sb.append(str).append(System.lineSeparator());
            }
            String content = sb.toString();

            int questionType = QuestionType.QUESTION5.getCode();
            long questionId = idGenerator.nextId();
            String extra = "";
            Question question = new Question(questionId, content, questionType, extra);

            List<String> valList = List.of("233");
            List<QuestionOption> questionOptionList1 = new ArrayList<>();
            for (int i = 0; i < valList.size(); i++) {
                String optionContent2 = valList.get(i);
                int pos = i+1;
                boolean correct2 = i == valList.size()-1;
                QuestionOption questionOption2 = new QuestionOption(questionId, optionContent2, pos, correct2);
                questionOptionList1.add(questionOption2);
            }

            questionMapper.save(question);
            questionOptionMapper.saveAll(questionOptionList1);
        });
    }

    @Test
    public void parseQuestionTest() {
        String filePath = "/home/reghao/Dropbox/tiku/xxqg.json";
        JsonObject jsonObject = JsonConverter.jsonFileToObject(new File(filePath), JsonObject.class);
        List<AhaQuestion> questionList = new ArrayList<>();
        jsonObject.entrySet().forEach(entry -> {
            AhaQuestion question1 = new AhaQuestion();
            JsonElement jsonElement = entry.getValue();
            String correctAnswer = jsonElement.getAsString();
            question1.setCorrectAnswer(correctAnswer);

            String key = entry.getKey();
            String[] arr = key.split("\\|");
            for (int i = 1; i < arr.length; i++) {
                question1.getAnswers().add(arr[i]);
            }

            String question = arr[0];
            if (question.contains("来源：")) {
                String[] arr1 = question.split("来源：");
                question1.setTitle(arr1[0]);
                question1.setSource("来源：" + arr1[1]);
            } else {
                question1.setTitle(question);
            }
            questionList.add(question1);
        });

        for (int i = 0; i < questionList.size(); i++) {
            AhaQuestion ahaQuestion = questionList.get(i);
            long questionId = idGenerator.nextId();
            String content = ahaQuestion.getTitle();
            String extra = ahaQuestion.getSource();
            String correctAnswer = ahaQuestion.getCorrectAnswer();

            int questionType = QuestionType.QUESTION1.getCode();
            int size = ahaQuestion.getAnswers().size();
            if (size == 2 && (correctAnswer.equals("正确") || correctAnswer.equals("错误"))) {
                questionType = QuestionType.QUESTION4.getCode();
            }

            Question question = new Question(questionId, content, questionType, extra);
            List<String> answers = ahaQuestion.getAnswers();
            List<QuestionOption> questionOptionList = new ArrayList<>();
            for (int j = 0; j < answers.size(); j++) {
                String answer = answers.get(j);
                boolean correct = answer.equalsIgnoreCase(correctAnswer);
                int pos = j+1;

                QuestionOption questionOption = new QuestionOption(questionId, answer, pos, correct);
                questionOptionList.add(questionOption);
            }
            question.setQuestionOptions(questionOptionList);

            questionMapper.save(question);
            questionOptionMapper.saveAll(questionOptionList);
        }
    }

    @NoArgsConstructor
    @Setter
    @Getter
    class AhaQuestion {
        private String title;
        private List<String> answers = new ArrayList<>();
        private String correctAnswer;
        private String source;
    }

    @Test
    public void gaokaoQuestionTest() {
        String baseDir = "/home/reghao/Dropbox/tiku/gaokao/objective";
        File dir = new File(baseDir);
        for (File file : dir.listFiles()) {
            parseQuestion(file.getAbsolutePath());
        }

        baseDir = "/home/reghao/Dropbox/tiku/gaokao/subjective";
        dir = new File(baseDir);
        for (File file : dir.listFiles()) {
            parseQuestion1(file.getAbsolutePath());
        }
    }

    private void parseQuestion(String filePath) {
        int subjectId = 1;
        if (filePath.contains("Math")) {
            subjectId = 2;
        } else if (filePath.contains("English")) {
            subjectId = 3;
        } else if (filePath.contains("Physics")) {
            subjectId = 4;
        } else if (filePath.contains("Chemistry")) {
            subjectId = 5;
        } else if (filePath.contains("Biology")) {
            subjectId = 6;
        } else if (filePath.contains("Political")) {
            subjectId = 7;
        } else if (filePath.contains("History")) {
            subjectId = 8;
        } else if (filePath.contains("Geography")) {
            subjectId = 9;
        }

        JsonElement jsonElement3 = JsonConverter.jsonFileToObject(new File(filePath), JsonElement.class);
        JsonObject jsonObject = jsonElement3.getAsJsonObject();
        for (JsonElement jsonElement0 : jsonObject.get("example").getAsJsonArray()) {
            JsonObject jsonObject0 = jsonElement0.getAsJsonObject();
            try {
                int year = jsonObject0.get("year").getAsInt();
                String category = jsonObject0.get("category").getAsString();
                String question = jsonObject0.get("question").getAsString();
                String questionContent0 = getHtml1(question);

                String[] questionArr = question.split("\\n");
                int len = questionArr.length;
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < len-4; i++) {
                    sb.append(questionArr[i]).append(System.lineSeparator());
                }

                String questionContent = sb.toString();
                if (questionContent.isBlank()) {
                    System.out.printf("%s -> 单选题格式不正确\n", filePath);
                    continue;
                }
                questionContent = getHtml1(questionContent);

                List<String> questionOptions = new ArrayList<>();
                for (int i = len-4; i < questionArr.length; i++) {
                    String questionOption = getHtml1(questionArr[i]);
                    questionOptions.add(questionOption);
                }

                List<String> answers = new ArrayList<>();
                for (JsonElement answerElement : jsonObject0.get("answer").getAsJsonArray()) {
                    answers.add(answerElement.getAsString());
                }
                int answerNum = 0;
                if (answers.size() == 1) {
                    String answer = jsonObject0.get("answer").getAsString();
                    if (answer.equalsIgnoreCase("A")) {
                        answerNum = 1;
                    } else if (answer.equalsIgnoreCase("B")) {
                        answerNum = 2;
                    } else if (answer.equalsIgnoreCase("C")) {
                        answerNum = 3;
                    } else if (answer.equalsIgnoreCase("D")) {
                        answerNum = 4;
                    }
                } else {
                    System.out.printf("%s -> 单选题答案超过1个\n", filePath);
                }

                String analysis = jsonObject0.get("analysis").getAsString();
                analysis = getHtml1(analysis);
                int score = jsonObject0.get("score").getAsInt();

                String extra = String.format("%s 分 | %s | %s", score, year, category);
                int questionType = QuestionType.QUESTION1.getCode();
                long questionId = idGenerator.nextId();

                //Question question0 = new Question(questionId, questionContent, questionType, extra);
                Question question0 = new Question(questionId, questionContent0, questionType, extra);
                question0.setAnalysis(analysis);
                question0.setSubjectId(subjectId);
                List<QuestionOption> questionOptions0 = new ArrayList<>();
                for (int i = 0; i < questionOptions.size(); i++) {
                    String content0 = questionOptions.get(i);
                    int pos = i + 1;
                    boolean correct = pos == answerNum;
                    QuestionOption questionOption0 = new QuestionOption(questionId, content0, pos, correct);
                    questionOptions0.add(questionOption0);
                }
                question0.setQuestionOptions(questionOptions0);

                questionMapper.save(question0);
                questionOptionMapper.saveAll(questionOptions0);
            } catch (Exception e) {
                if (e instanceof ArrayIndexOutOfBoundsException) {
                    System.out.printf("%s -> ArrayIndexOutOfBoundsException\n", filePath);
                } else {
                    System.out.println(filePath);
                    e.printStackTrace();
                }
            }
        }
    }

    private void parseQuestion1(String filePath) {
        int subjectId = 1;
        if (filePath.contains("Math")) {
            subjectId = 2;
        } else if (filePath.contains("English")) {
            subjectId = 3;
        } else if (filePath.contains("Physics")) {
            subjectId = 4;
        } else if (filePath.contains("Chemistry")) {
            subjectId = 5;
        } else if (filePath.contains("Biology")) {
            subjectId = 6;
        } else if (filePath.contains("Political")) {
            subjectId = 7;
        } else if (filePath.contains("History")) {
            subjectId = 8;
        } else if (filePath.contains("Geography")) {
            subjectId = 9;
        }

        JsonElement jsonElement3 = JsonConverter.jsonFileToObject(new File(filePath), JsonElement.class);
        JsonObject jsonObject = jsonElement3.getAsJsonObject();
        for (JsonElement jsonElement0 : jsonObject.get("example").getAsJsonArray()) {
            JsonObject jsonObject0 = jsonElement0.getAsJsonObject();
            try {
                int year = jsonObject0.get("year").getAsInt();
                String category = jsonObject0.get("category").getAsString();
                String question = jsonObject0.get("question").getAsString();
                String answer = jsonObject0.get("answer").getAsString();
                String analysis = jsonObject0.get("analysis").getAsString();
                int score = jsonObject0.get("score").getAsInt();

                String extra = String.format("%s 分 | %s | %s", score, year, category);
                int questionType = QuestionType.QUESTION6.getCode();
                long questionId = idGenerator.nextId();

                String questionContent0 = getHtml1(question);
                Question question0 = new Question(questionId, questionContent0, questionType, extra);
                question0.setAnalysis(analysis);
                question0.setSubjectId(subjectId);
                questionMapper.save(question0);
            } catch (Exception e) {
                if (e instanceof ArrayIndexOutOfBoundsException) {
                    System.out.printf("%s -> ArrayIndexOutOfBoundsException\n", filePath);
                } else {
                    System.out.println(filePath);
                    e.printStackTrace();
                }
            }
        }
    }

    private String getHtml1(String content) {
        String tag1 = "<span class=\"math-tex\">\\(";
        String tag2 = "\\)</span>";
        int count = 1;
        while (content.contains("$")) {
            if (count%2 != 0) {
                content = StringUtils.replaceOnce(content, "$", tag1);
                //question1 = question1.replaceFirst("\\$", tag1);
            } else {
                content = StringUtils.replaceOnce(content, "$", tag2);
                //question1 = question1.replaceFirst("\\$", tag2);
            }
            count++;
        }
        content = content.replace("\n", "<br>");
        return content;
    }

    @Autowired
    PaperService paperService;
    @Test
    public void createPaperTest() {
        List<PaperQuestion> paperQuestions = new ArrayList<>();
        List<PaperQuestion> paperQuestions1 = getObjective(10);
        List<PaperQuestion> paperQuestions2 = getSubjective(2);
        paperQuestions.addAll(paperQuestions1);
        //paperQuestions.addAll(paperQuestions2);

        int totalScore = paperQuestions.stream().mapToInt(PaperQuestion::getScore).sum();
        Double passScoreDouble = totalScore * 0.6;
        int passScore = passScoreDouble.intValue();
        String paperName = "主客观10题(自测)";
        paperName = "客观10题";
        //paperName = "主客观10题";

        PaperAddDto paperAddDto = new PaperAddDto();
        paperAddDto.setExamName(paperName);
        paperAddDto.setTotalScore(totalScore);
        paperAddDto.setPassScore(passScore);
        paperAddDto.setExamDuration(90);
        paperAddDto.setStartTime(new Date());
        paperAddDto.setEndTime(new Date());
        paperAddDto.setPaperQuestions(paperQuestions);
        paperService.createExamPaper(paperAddDto);
    }

    private List<PaperQuestion> getObjective(int size) {
        int questionType = QuestionType.QUESTION1.getCode();
        QuestionQuery questionQuery = new QuestionQuery.Builder()
                .pageNumber(1)
                .pageSize(size)
                .type(questionType)
                .build();
        Page page = questionQuery.getPage();
        List<Question> questions = questionMapper.findQuestionByPage(page, questionQuery);
        List<PaperQuestion> paperQuestions = new ArrayList<>();
        for (int i = 0; i < questions.size(); i++) {
            Question question = questions.get(i);
            int pos = i + 1;
            int score = 1;
            paperQuestions.add(new PaperQuestion(pos, question, score));
        }

        return paperQuestions;
    }

    private List<PaperQuestion> getSubjective(int size) {
        int questionType = QuestionType.QUESTION6.getCode();
        QuestionQuery questionQuery = new QuestionQuery.Builder()
                .pageNumber(1)
                .pageSize(size)
                .type(questionType)
                .build();
        Page page = questionQuery.getPage();
        List<Question> questions = questionMapper.findQuestionByPage(page, questionQuery);
        List<PaperQuestion> paperQuestions = new ArrayList<>();
        for (int i = 0; i < questions.size(); i++) {
            Question question = questions.get(i);
            int pos = i + 1;
            int score = 1;
            paperQuestions.add(new PaperQuestion(pos, question, score));
        }

        return paperQuestions;
    }

    @Test
    public void getPaperAnswerTest() {
        int paperId = 1;
        //Paper paper = paperMapper.findById(paperId);
        List<PaperQuestion> paperQuestions = paperQuestionMapper.findByPaperId(paperId);

        int resultId = 1;
        //Map<Long, List<Object>> map = getPaperAnswersFromResult(resultId);
        System.out.println();
    }

    private Map<Long, List<Object>> getPaperAnswersFromResult(int resultId) {
        Map<Long, List<Object>> map = new HashMap<>();
        List<PaperAnswer> paperAnswerList = paperAnswerMapper.findByResultId(resultId);
        paperAnswerList.forEach(paperAnswer -> {
            long questionId = paperAnswer.getQuestionId();
            int type = paperAnswer.getQuestionType();
            List<String> answers = List.of(paperAnswer.getAnswer());
            List<Object> objectList;
            if (type == QuestionType.QUESTION1.getCode() || type == QuestionType.QUESTION4.getCode()) {
                objectList = answers.stream()
                        .map(val -> val.isBlank() ? -1 : Integer.parseInt(val))
                        .collect(Collectors.toList());

                List<QuestionOption> list = questionOptionMapper.findByQuestionId(questionId);
                List<String> correctAnswers = list.stream()
                        .filter(QuestionOption::getCorrect)
                        .map(QuestionOption::getContent)
                        .collect(Collectors.toList());
            } else {
                objectList = Arrays.asList(answers);
            }

            map.put(questionId, objectList);
        });

        return map;
    }
}
