import {
    extractAnswerImages,
    extractTitleImages,
    formatQuestionHtml,
    getQuestionAnswerSource,
    getQuestionStemSource,
    isHtmlContent,
} from '@/utils/questionHtml';
import type { QuestionOption, ReportQuestion, ReportQuestionSummary } from './data';

export type QuestionStatus = 'correct' | 'wrong' | 'unanswered';

export const normalizeAnswer = (value: unknown) => {
    if (Array.isArray(value)) return value.join('、');
    if (value == null) return '';
    return String(value)
        .replace(/^\[|\]$/g, '')
        .replace(/"/g, '')
        .replace(/,/g, '、');
};

export const formatRateText = (value: unknown) => {
    if (value == null || value === '') return '--';
    const num = Number(value);
    if (!Number.isNaN(num)) {
        const rate = num <= 1 ? num * 100 : num;
        return `${Math.round(rate * 10) / 10}%`;
    }
    const text = String(value);
    return text.includes('%') ? text : `${text}%`;
};

export const getQuestionStatus = (item: Record<string, unknown>): QuestionStatus => {
    const correct =
        item.correctResult === 1 ||
        item.correctResult === true ||
        item.markFlag === 1 ||
        item.markFlag === true;
    if (correct) return 'correct';
    if (!item.submitAnswer && !item.submitAnswerPic) return 'unanswered';
    return 'wrong';
};

const stripImageUrlsFromText = (text: string) => {
    let result = text;
    const links = text.match(/https?:\/\/[^\s,]+/gi) || [];
    links.forEach((link) => {
        result = result.replace(link, '');
    });
    return result.replace(/[,，、\s]+$/g, '').replace(/^[,，、\s]+/g, '').trim();
};

const buildStudentAnswer = (item: Record<string, unknown>) => {
    const studentAnswerImages = extractAnswerImages(item);
    let textAnswer = normalizeAnswer(item.submitAnswer);

    if (textAnswer) {
        const onlyUrls = stripImageUrlsFromText(textAnswer) === '' && studentAnswerImages.length > 0;
        if (onlyUrls) {
            textAnswer = '';
        } else {
            textAnswer = stripImageUrlsFromText(textAnswer);
        }
    }

    if (!textAnswer && !studentAnswerImages.length) {
        return { studentAnswer: '未作答', studentAnswerHtml: '', studentAnswerImages: [] };
    }

    if (textAnswer && isHtmlContent(textAnswer)) {
        return {
            studentAnswer: '',
            studentAnswerHtml: formatQuestionHtml(textAnswer),
            studentAnswerImages,
        };
    }

    return {
        studentAnswer: textAnswer,
        studentAnswerHtml: '',
        studentAnswerImages,
    };
};

const getQuestionFullScore = (item: Record<string, unknown>) => Number(item.score ?? item.titleScore ?? 0);

const getQuestionActualScore = (item: Record<string, unknown>) =>
    Number(item.actualScore ?? item.markScore ?? item.answerScore ?? item.gotScore ?? 0);

const formatQuestionScoreText = (item: Record<string, unknown>) => {
    const fullScore = getQuestionFullScore(item);
    const actualScore = getQuestionActualScore(item);
    return `${actualScore}/${fullScore || actualScore || 0}`;
};

const OPTION_LABELS = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'];

/** 从原始题目数据中解析选项列表，参考 web 版 Question.vue 的 rawParsedOptions / parsedOptionHtml 逻辑 */
const parseQuestionOptions = (item: Record<string, unknown>): QuestionOption[] => {
    // 1. 优先解析 optionHtml（标准格式：JSON 数组，每项含 html 属性）
    const optHtml = item.optionHtml;
    if (optHtml != null) {
        try {
            const parsed = typeof optHtml === 'string' ? JSON.parse(optHtml) : optHtml;
            if (Array.isArray(parsed)) {
                return parsed.map((opt: any, idx: number) => ({
                    label: OPTION_LABELS[idx] || String.fromCharCode(65 + idx),
                    value: typeof opt === 'string' ? opt : (opt.html || opt.value || opt.optionValue || ''),
                }));
            }
        } catch {
            /* ignore parse error */
        }
    }

    // 2. 尝试 optionsMu / options（多种格式）
    let opts: any = item.optionsMu ?? item.options ?? item.optionList;
    if (opts == null) return [];

    if (typeof opts === 'string') {
        try {
            opts = JSON.parse(opts);
        } catch {
            return [];
        }
    }
    if (!Array.isArray(opts)) return [];

    // 3. 扁平化多余嵌套 [[...]] → [...]
    while (opts.length === 1 && Array.isArray(opts[0])) {
        opts = opts[0];
    }

    // 4. 数组的数组（完形填空/阅读理解结构）→ 取第一组选项作为当前题目的选项
    if (opts.length && Array.isArray(opts[0])) {
        const firstGroup = opts[0];
        if (Array.isArray(firstGroup)) {
            return firstGroup.map((opt: any, idx: number) => {
                const value = typeof opt === 'string' ? opt : (opt.html || opt.value || opt.optionValue || '');
                return {
                    label: OPTION_LABELS[idx] || String.fromCharCode(65 + idx),
                    value: String(value || '').replace(/http:\/\//gi, 'https://'),
                };
            });
        }
    }

    // 5. 纯字符串数组 → 简单选项
    if (opts.every((i: any) => typeof i === 'string')) {
        return opts.map((opt: string, idx: number) => ({
            label: OPTION_LABELS[idx] || String.fromCharCode(65 + idx),
            value: String(opt || '').replace(/http:\/\//gi, 'https://'),
        }));
    }

    // 6. 对象数组（带 html/value 属性的对象）
    return opts.map((opt: any, idx: number) => ({
        label: opt.label || opt.optionKey || OPTION_LABELS[idx] || String.fromCharCode(65 + idx),
        value: String(opt.html || opt.value || opt.optionValue || opt.content || '').replace(/http:\/\//gi, 'https://'),
    }));
};

export const mapPaperQuestionSummary = (item: Record<string, unknown>, index: number): ReportQuestionSummary => {
    return {
        no: Number(item.titleSort ?? item.sort ?? index + 1),
        type: String(item.titleChannelTypeName || item.chanelTypeName || '综合题'),
        score: formatQuestionScoreText(item),
        status: getQuestionStatus(item),
        classRate: formatRateText(
            item.classScoreRate ?? item.classRate ?? item.classAvgScoreRate ?? item.classGotScoreRate,
        ),
        schoolRate: formatRateText(
            item.schoolScoreRate ?? item.schoolRate ?? item.schoolAvgScoreRate ?? item.schoolGotScoreRate,
        ),
        knowledge: String(item.knowledgeName || item.knowledge || item.knowledgePointName || '待归类'),
    };
};

export const mapPaperQuestionSummaries = (list: unknown[]) =>
    (Array.isArray(list) ? list : []).map((item, index) =>
        mapPaperQuestionSummary(item as Record<string, unknown>, index),
    );

export const mapPaperQuestion = (item: Record<string, unknown>, index: number): ReportQuestion => {
    const status = getQuestionStatus(item);
    const stemSource = getQuestionStemSource(item);
    const answerSource = getQuestionAnswerSource(item);
    const { studentAnswer, studentAnswerHtml, studentAnswerImages } = buildStudentAnswer(item);
    const stemImages = extractTitleImages(stemSource);
    const options = parseQuestionOptions(item);

    return {
        no: Number(item.titleSort ?? item.sort ?? index + 1),
        type: String(item.titleChannelTypeName || item.chanelTypeName || '综合题'),
        score: formatQuestionScoreText(item),
        status,
        stemHtml: formatQuestionHtml(stemSource, { stripImages: true }),
        stemImages,
        options,
        correctAnswerHtml: formatQuestionHtml(answerSource),
        studentAnswer,
        studentAnswerHtml,
        studentAnswerImages,
        classRate: formatRateText(
            item.classScoreRate ?? item.classRate ?? item.classAvgScoreRate ?? item.classGotScoreRate,
        ),
        schoolRate: formatRateText(
            item.schoolScoreRate ?? item.schoolRate ?? item.schoolAvgScoreRate ?? item.schoolGotScoreRate,
        ),
        knowledge: String(item.knowledgeName || item.knowledge || item.knowledgePointName || '待归类'),
    };
};

export const mapPaperQuestions = (list: unknown[]) =>
    (Array.isArray(list) ? list : []).map((item, index) =>
        mapPaperQuestion(item as Record<string, unknown>, index),
    );

/** 兼容旧版 mock 数据结构 */
export const normalizeLegacyQuestion = (item: Record<string, unknown>): ReportQuestion => {
    const legacy = item as ReportQuestion & { stem?: string; correctAnswer?: string };
    if (legacy.stemHtml) return legacy as ReportQuestion;
    const legacyOptions = Array.isArray((item as any).options) ? (item as any).options : [];
    return {
        no: Number(legacy.no),
        type: String(legacy.type),
        score: String(legacy.score),
        status: legacy.status,
        stemHtml: String(legacy.stem || ''),
        stemImages: [],
        options: legacyOptions,
        correctAnswerHtml: String(legacy.correctAnswer || ''),
        studentAnswer: String(legacy.studentAnswer || ''),
        studentAnswerHtml: '',
        studentAnswerImages: [],
        classRate: String(legacy.classRate),
        schoolRate: String(legacy.schoolRate),
        knowledge: String(legacy.knowledge),
    };
};
