package com.seer.teach.teacher.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seer.teach.common.enums.QuestionTypesEnums;
import com.seer.teach.teacher.common.resp.WrongQuestionPageListResp;
import com.seer.teach.teacher.convert.QuestionConvert;
import com.seer.teach.teacher.module.entity.BankQuestionsEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class WrongQuestionUtils {

    /**
     * 构建提示词
     *
     * @param originalQuestion 原始错题
     * @param knowId           知识点Id
     * @param type             题型
     * @param count            数量
     * @return 提示词
     */
    public static String buildPromptForSimilarQuestions(BankQuestionsEntity originalQuestion, Integer knowId, Integer type, Integer count) {
        return String.format(
                "请根据以下题目生成 %d 道类似但不同的变式题，保持相同知识点和难度：\n\n" +
                        "原题：%s\n" +
                        "要求：\n" +
                        "- 题型相同（%s）\n" +
                        "- 知识点一致（知识点ID: %d）\n" +
                        "- 每道题表述方式略有变化（如替换关键词、数字、情境）\n" +
                        "- 返回格式为 JSON 数组，每项包含：\n" +
                        "  - title: 题目文本\n" +
                        "  - answer: 正确答案\n" +
                        "  - solution: 解析\n" +
                        "  - html: HTML 格式题目内容（含【正确答案】、解析等）\n" +
                        "  - type: 题型\n" +
                        "  - isNeedImage: 是否需要图片（0/1）\n" +
                        "  - difficulty: 难度（1.0~5.0）\n" +
                        "  - options: 选项列表（如果是选择题）\n" +
                        " \n\n注意：请严格按照以下HTML格式输出每道题：\\n\" +\n" +
                        "            \"<h4>题目内容</h4>\\n\" +\n" +
                        "            \"A. 选项A<br/>\\n\" +\n" +
                        "            \"B. 选项B<br/>\\n\" +\n" +
                        "            \"C. 选项C<br/>\\n\" +\n" +
                        "            \"D. 选项D<br/>\\n\" +\n" +
                        "            \"<p><b>答案:</b> 正确答案</p>\\n\" +\n" +
                        "            \"<p><b>解析:</b> 解析内容</p>\"",
                count,
                originalQuestion.getTitle(),
                Objects.requireNonNull(QuestionTypesEnums.getByCode(type)).getMsg(),
                knowId
        );
    }

    /**
     * 解析大模型响应（用于题目生成场景）
     *
     * @param content 响应体
     * @return 生成的题目列表
     */
    public static List<JsonNode> parseLLMResponse(String content) {
        try {
            log.info("解析大模型响应，内容: {}", content);
            // 解析内容中的JSON数组
            content = content.trim();
            if (content.startsWith("```json")) {
                content = content.substring(7, content.length() - 3).trim();
            } else if (content.startsWith("```")) {
                content = content.substring(3, content.length() - 3).trim();
            }
            // 解析JSON响应
            ObjectMapper objectMapper = new ObjectMapper();
            // 解析题目数组
            JsonNode questionsArray = objectMapper.readTree(content);
            List<JsonNode> result = new ArrayList<>();
            if (questionsArray.isArray()) {
                for (JsonNode questionNode : questionsArray) {
                    result.add(questionNode);
                }
            }
            return result;
        } catch (Exception e) {
            log.error("解析大模型响应时发生异常", e);
            return Collections.emptyList();
        }
    }

    /**
     * 构造默认的HTML格式
     *
     * @param node JSON节点
     * @return HTML格式
     */
    public static String constructDefaultHtml(JsonNode node) {
        StringBuilder result = new StringBuilder();
        // 题目标题
        result.append("<h4>").append(node.has("title") ? node.get("title").asText() : "").append("</h4>");
        // 选项（如果是选择题）
        if (node.has("options") && !node.get("options").isEmpty()) {
            JsonNode optionsArray = node.get("options");
            for (JsonNode optionNode : optionsArray) {
                String content = optionNode.has("content") ? optionNode.get("content").asText() : "";
                result.append("\n            ").append(content).append("<br/>");
            }
        }
        // 处理答案显示格式
        String answerText = "";
        if (node.has("answer")) {
            String rawAnswer = node.get("answer").asText();
            // 判断题答案转换
            if ("true".equalsIgnoreCase(rawAnswer)) {
                answerText = "对";
            } else if ("false".equalsIgnoreCase(rawAnswer)) {
                answerText = "错";
            } else {
                answerText = rawAnswer;
            }
        }
        // 正确答案
        result.append("\n\n    <p><b>答案:</b> ").append(answerText).append("</p>");
        // 解析
        result.append("\n\n    <p><b>解析:</b> ").append(node.has("solution") ? node.get("solution").asText() : "").append("</p>");
        return result.toString();
    }

    /**
     * 转换答案格式，特别是处理判断题的 true/false 到 对/错 的转换
     *
     * @param rawAnswer    原始答案
     * @param questionType 题目类型
     * @return 转换后的答案
     */
    public static String convertAnswerFormat(String rawAnswer, Integer questionType) {
        // 如果是判断题
        if (questionType != null && questionType.equals(QuestionTypesEnums.BOOLEAN_QUESTIONS.getCode())) {
            if ("true".equalsIgnoreCase(rawAnswer) || "是".equalsIgnoreCase(rawAnswer) || "正确".equalsIgnoreCase(rawAnswer)) {
                return "对";
            } else if ("false".equalsIgnoreCase(rawAnswer) || "否".equalsIgnoreCase(rawAnswer) || "错误".equalsIgnoreCase(rawAnswer)) {
                return "错";
            }
        }
        return rawAnswer;
    }

    /**
     * 从完整HTML中提取题目和选项部分
     *
     * @param fullHtml 完整的HTML内容（包含题目、选项、答案、解析）
     * @return 仅包含题目和选项的HTML内容
     */
    public static String extractQuestionAndOptions(String fullHtml) {
        if (fullHtml == null || fullHtml.isEmpty()) {
            return "";
        }
        // 查找答案部分的开始位置，截取在此之前的内容
        int answerIndex = fullHtml.indexOf("<p><b>答案:</b>");
        if (answerIndex != -1) {
            return fullHtml.substring(0, answerIndex).trim();
        }
        // 如果没找到答案部分，尝试查找解析部分
        int analysisIndex = fullHtml.indexOf("<p><b>解析:</b>");
        if (analysisIndex != -1) {
            return fullHtml.substring(0, analysisIndex).trim();
        }
        return fullHtml;
    }

    /**
     * 给题目HTML内容添加学生作答信息，并进行格式化展示
     *
     * @param question      题目实体
     * @param studentAnswer 学生的答案
     * @return 带有学生答案的响应对象
     */
    public static WrongQuestionPageListResp addStudentAnswerToQuestion(BankQuestionsEntity question, String studentAnswer) {
        WrongQuestionPageListResp resp = QuestionConvert.INSTANCE.toWrongQuestionPageListResp(question);
        String originalHtml = resp.getHtml();
        if (originalHtml == null) return resp;
        String safeStudentAnswer = escapeHtml(studentAnswer);
        // 处理解析部分与正确答案标签
        String processed = originalHtml
                .replaceAll("<!--\\s*题目解析\\s*-->\\s*<p><b>解析:</b>", "<p>解析：")
                .replaceAll("<p>\\s*<b>答案:</b>\\s*", "<p>【正确答案】 ");
//        String redX = " ❌";
        // 构建学生答案段
        String studentSegment = "<p>【你的答案】 "
                + (safeStudentAnswer.isEmpty() ? "" : safeStudentAnswer)
                + "</p>\n\n";
        // 插入到正确答案之前
        processed = processed.replaceFirst("<p>【正确答案】", studentSegment + "<p>【正确答案】");
        resp.setHtml(processed);
        return resp;
    }

    /**
     * 对输入字符串执行HTML转义操作以防止XSS攻击
     *
     * @param s 待转义的原始字符串
     * @return 已经完成HTML转义的安全字符串
     */
    public static String escapeHtml(String s) {
        if (s == null) return "";
        return s.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#39;");
    }
}
