/** 题目 HTML 处理（与学生端 doWork/Question 保持一致） */

const LATEX_RENDER_URL = 'https://latex.codecogs.com/svg.image?';

export const fixMathSymbolsInHtml = (html: string): string => {
    if (html == null || typeof html !== 'string') return '';
    let t = html;
    t = t.replace(/\uFE63/g, '\u2212');
    t = t.replace(/<(?![a-zA-Z/!])/g, '&lt;');
    t = t.replace(/ > /g, ' &gt; ');
    t = t.replace(/AUB/g, 'A∪B');
    return t;
};

const latexToImageUrl = (latex: string): string => {
    if (!latex) return '';
    let formula = latex.trim();

    const punctuationMap: Record<string, string> = {
        '，': ',', '。': '.', '：': ':', '；': ';', '！': '!', '？': '?',
        '（': '(', '）': ')', '【': '[', '】': ']', '｛': '{', '｝': '}',
        '《': '<', '》': '>',
        "\u201c": '"', "\u201d": '"', "\u2018": "'", "\u2019": "'",
        '＋': '+', '－': '-', '\u2212': '-', '×': '*', '÷': '/',
        '＝': '=', '＜': '<', '＞': '>', '％': '%', '＆': '&',
        '＊': '*', '＠': '@', '＃': '#', '＄': '$', '＾': '^',
        '～': '~', '｜': '|', '＼': '\\', '／': '/', '　': ' ',
    };
    for (const [cn, en] of Object.entries(punctuationMap)) {
        formula = formula.split(cn).join(en);
    }

    const mathSymbolMap: Record<string, string> = {
        '∈': ' \\in ', '∉': ' \\notin ', '⊂': ' \\subset ', '⊃': ' \\supset ',
        '⊆': ' \\subseteq ', '⊇': ' \\supseteq ', '∪': ' \\cup ', '∩': ' \\cap ',
        '∅': ' \\emptyset ',
        '≤': ' \\leq ', '≥': ' \\geq ', '≠': ' \\neq ', '≈': ' \\approx ',
        '≡': ' \\equiv ', '∝': ' \\propto ',
        '±': ' \\pm ', '∓': ' \\mp ', '×': ' \\times ', '÷': ' \\div ',
        '·': ' \\cdot ', '∘': ' \\circ ',
        'α': '\\alpha ', 'β': '\\beta ', 'γ': '\\gamma ', 'δ': '\\delta ',
        'ε': '\\varepsilon ', 'θ': '\\theta ', 'λ': '\\lambda ', 'μ': '\\mu ',
        'σ': '\\sigma ', 'φ': '\\varphi ', 'ω': '\\omega ',
        'Δ': '\\Delta ', 'Σ': '\\Sigma ', 'Ω': '\\Omega ',
        '∞': '\\infty ', '∂': '\\partial ', '∇': '\\nabla ', '∫': '\\int ',
        '∑': '\\sum ', '∏': '\\prod ', '√': '\\sqrt ', '∠': '\\angle ',
        '⊥': '\\perp ', '∥': '\\parallel ',
        '→': '\\to ', '⇒': '\\Rightarrow ', '⇔': '\\Leftrightarrow ',
        '∀': '\\forall ', '∃': '\\exists ', '¬': '\\neg ',
        '∧': '\\land ', '∨': '\\lor ',
    };
    for (const [symbol, latexCmd] of Object.entries(mathSymbolMap)) {
        formula = formula.split(symbol).join(latexCmd);
    }

    formula = formula.replace(/\b([RNZQC])\+/g, '$1^+');
    formula = formula.replace(/\b([RNZQC])\*/g, '$1^*');
    formula = formula
        .replace(/\\overset\s*\{\s*\\rightarrow\s*\}\s*\{([^}]+)\}/g, '\\vec{$1}')
        .replace(/\\text\s*\{\s*π\s*\}/g, '\\pi')
        .replace(/\\text\s*\{\s*sin\s*\}/gi, '\\sin')
        .replace(/\\text\s*\{\s*cos\s*\}/gi, '\\cos')
        .replace(/\\text\s*\{\s*tan\s*\}/gi, '\\tan')
        .replace(/\\text\s*\{\s*log\s*\}/gi, '\\log')
        .replace(/π/g, '\\pi');

    const encoded = encodeURIComponent(formula);
    return `${LATEX_RENDER_URL}\\inline&space;\\dpi{200}&space;${encoded}`;
};

const isSimpleFormula = (formula: string): boolean => {
    const complexPatterns = [
        /\\frac\b/, /\\sqrt\b/, /\\sum\b/, /\\int\b/, /\\prod\b/, /\\lim\b/,
        /\\vec\b/, /\\overline\b/, /\\underline\b/, /\\overset\b/, /\\underset\b/,
        /\\binom\b/, /\\matrix\b/, /\\begin\b/,
        /\^{[^}]+}/, /_{[^}]+}/,
    ];
    return !complexPatterns.some((pattern) => pattern.test(formula));
};

const simpleFormulaToHtml = (formula: string): string => {
    let text = formula;
    text = text.replace(/\\text\s*\{([^}]*)\}/g, '$1');

    const greekMap: Record<string, string> = {
        '\\alpha': 'α', '\\beta': 'β', '\\gamma': 'γ', '\\delta': 'δ',
        '\\epsilon': 'ε', '\\varepsilon': 'ε', '\\theta': 'θ', '\\lambda': 'λ',
        '\\mu': 'μ', '\\pi': 'π', '\\sigma': 'σ', '\\phi': 'φ', '\\varphi': 'φ',
        '\\omega': 'ω', '\\Delta': 'Δ', '\\Sigma': 'Σ', '\\Omega': 'Ω',
    };
    for (const [latex, symbol] of Object.entries(greekMap)) {
        text = text.split(latex).join(symbol);
    }

    text = text.replace(/\\sin\b/g, 'sin');
    text = text.replace(/\\cos\b/g, 'cos');
    text = text.replace(/\\tan\b/g, 'tan');
    text = text.replace(/\\log\b/g, 'log');
    text = text.replace(/\\ln\b/g, 'ln');
    text = text.replace(/\\infty\b/g, '∞');
    text = text.replace(/\\pm\b/g, '±');
    text = text.replace(/\\times\b/g, '×');
    text = text.replace(/\\div\b/g, '÷');
    text = text.replace(/\\leq\b/g, '≤');
    text = text.replace(/\\geq\b/g, '≥');
    text = text.replace(/\\neq\b/g, '≠');
    text = text.replace(/\\in\b/g, '∈');
    text = text.replace(/\\subset\b/g, '⊂');
    text = text.replace(/\\cup\b/g, '∪');
    text = text.replace(/\\cap\b/g, '∩');
    text = text.replace(/\\emptyset\b/g, '∅');
    text = text.replace(/\\cdot\b/g, '·');
    text = text.replace(/\\to\b/g, '→');

    const superscriptMap: Record<string, string> = {
        '0': '⁰', '1': '¹', '2': '²', '3': '³', '4': '⁴',
        '5': '⁵', '6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹',
        '+': '⁺', '-': '⁻', 'n': 'ⁿ',
    };
    const subscriptMap: Record<string, string> = {
        '0': '₀', '1': '₁', '2': '₂', '3': '₃', '4': '₄',
        '5': '₅', '6': '₆', '7': '₇', '8': '₈', '9': '₉',
        '+': '₊', '-': '₋', 'n': 'ₙ', 'i': 'ᵢ', 'k': 'ₖ',
    };
    text = text.replace(/\^([0-9n+\-])/g, (_, char) => superscriptMap[char] || `^${char}`);
    text = text.replace(/_([0-9nik+\-])/g, (_, char) => subscriptMap[char] || `_${char}`);
    text = text.replace(/\\left\s*/g, '');
    text = text.replace(/\\right\s*/g, '');
    text = text.replace(/\\/g, '');

    return `<span class="formula-text" style="font-style:italic;">${text}</span>`;
};

export const processFormula = (html: string): string => {
    if (html == null || typeof html !== 'string') return '';
    if (!html) return '';

    const formulaRegex = /<span\s+((?:[^<>"']+|"[^"]*"|'[^']*')*)data-w-e-type=["']formula["']((?:[^<>"']+|"[^"]*"|'[^']*')*)>[\s\S]*?<\/span>/gi;

    return html.replace(formulaRegex, (match) => {
        const valueMatch = match.match(/data-value=["']([^"']+)["']/);
        if (!valueMatch) return match;

        let formula = valueMatch[1]
            .replace(/\\\\/g, '\\')
            .replace(/\\"/g, '"')
            .replace(/\\'/g, "'");

        if (!formula.trim()) return '';

        if (isSimpleFormula(formula)) {
            return simpleFormulaToHtml(formula);
        }

        const imageUrl = latexToImageUrl(formula);
        return `<img class="formula-img" src="${imageUrl}" style="height:1.4em;vertical-align:middle;" />`;
    });
};

export const isHtmlContent = (value: string) => /<[a-z][\s\S]*>/i.test(value);

export const formatQuestionHtml = (title?: string, options?: { stripImages?: boolean }) => {
    if (!title) return '';
    let t = String(title);
    if (options?.stripImages) {
        t = t.replace(/<img(?![^>]*formula-img)[^>]*\/?>/gi, '');
    }
    t = t.replace(/<u><\/u>/gi, '<u class="fill-blank"></u>');
    t = t.replace(/http:\/\//gi, 'https://');
    t = fixMathSymbolsInHtml(t);
    t = processFormula(t);
    return t;
};

export const getQuestionStemSource = (item: Record<string, unknown>) => {
    const pid = item.pidTitle ? String(item.pidTitle) : '';
    const stem = String(item.stemHtml || item.titleMu || item.title || item.stem || '');
    if (pid && stem) return `${pid}${stem}`;
    return pid || stem;
};

export const getQuestionAnswerSource = (item: Record<string, unknown>) =>
    String(item.answerMu ?? item.answer ?? '');

const IMAGE_URL_PATTERN = /\.(jpg|jpeg|png|gif|webp|bmp)(\?.*)?$/i;

export const isImageUrl = (url: string) => {
    const value = String(url || '').trim();
    if (!value) return false;
    if (IMAGE_URL_PATTERN.test(value)) return true;
    return /(?:cos\.|myqcloud|oss-|\/temp\/|\/upload)/i.test(value);
};

export const parseImageUrls = (raw: unknown) => {
    const urls = String(raw || '')
        .split(',')
        .map((item) => item.replace(/[`\s]/g, '').replace(/http:\/\//gi, 'https://').trim())
        .filter(Boolean);
    return urls.filter(isImageUrl);
};

export const extractAnswerImages = (item: Record<string, unknown>) => {
    const images = new Set<string>();
    parseImageUrls(item.submitAnswerPic).forEach((url) => images.add(url));

    const answer = String(item.submitAnswer || '');
    const links = answer.match(/https?:\/\/[^\s,]+/gi) || [];
    links.forEach((link) => {
        const url = link.replace(/http:\/\//gi, 'https://').trim();
        if (isImageUrl(url)) images.add(url);
    });

    return Array.from(images);
};

export const extractTitleImages = (html: string) => {
    if (!html) return [] as string[];
    const images: string[] = [];
    const imgRegex = /<img[^>]*\s*src=["']([^"']+)["'][^>]*\/?>/gi;
    let match;
    while ((match = imgRegex.exec(html)) !== null) {
        if (/formula-img/i.test(match[0])) continue;
        const url = (match[1] || '').trim().replace(/http:\/\//gi, 'https://');
        if (url) images.push(url);
    }
    return images;
};
