<template>
    <view class="q-item">
        <!-- 左侧题目 -->
        <scroll-view :class="['q-left', { expanded: isLeftExpanded }]" scroll-y :show-scrollbar="false">
            <view class="q-left-inner">
                <!-- 类型徽章 -->
                <view v-if="data?.titleChannelTypeName" class="q-type">
                    <text>{{ data.titleChannelTypeName }}</text>
                </view>

                <!-- 父题目 -->
                <view v-if="data?.pidTitle" class="q-pid">
                    <rich-text :nodes="filterTitleWithoutImages(data.pidTitle)" />
                </view>

                <!-- 主题目 -->
                <view v-if="stemText" class="q-title">
                    <rich-text :nodes="filterTitleWithoutImages(stemText)" />
                </view>

                <!-- 题目图片 -->
                <view v-if="titleImages.length" class="q-images">
                    <image
                        v-for="(img, imgIdx) in titleImages"
                        :key="imgIdx"
                        :src="img"
                        mode="widthFix"
                        @click="previewTitleImage(imgIdx)"
                    />
                </view>

                <!-- 音频按钮 -->
                <view v-if="data?.voiceUrl" class="q-voice" @click="playAudio">
                    <view :class="['voice-btn', { playing: isAudioPlay }]">
                        <view class="voice-wave"></view>
                        <view class="voice-wave delay-1"></view>
                        <view class="voice-wave delay-2"></view>
                        <svg viewBox="0 0 24 24" fill="none">
                            <path d="M3 10v4h4l5 4V6L7 10H3z"
                                fill="#FFFFFF" stroke="#FFFFFF" stroke-width="1.5"
                                stroke-linejoin="round" />
                            <path v-if="isAudioPlay" d="M16 8c1.5 1.5 1.5 6.5 0 8M19 5c3 3 3 11 0 14"
                                stroke="#FFFFFF" stroke-width="1.6" stroke-linecap="round" />
                        </svg>
                    </view>
                    <text class="voice-text">{{ isAudioPlay ? '点击暂停' : '点击播放' }}</text>
                </view>

                <!-- 子题目（非阅读 / 非完形） -->
                <view
                    v-if="data?.children?.length && questionType !== 'yuedu' && questionType !== 'wanxing'"
                    class="q-children"
                >
                    <view v-for="(child, cidx) in data.children" :key="child.id" class="q-child">
                        <rich-text :nodes="filterTitleWithoutImages(child.title, cidx)" />
                    </view>
                </view>

                <!-- 阅读理解 -->
                <view v-if="isYueDu && yueDuList.length" class="q-yuedu">
                    <view v-for="(subQ, sIdx) in yueDuList" :key="sIdx" class="q-yuedu-item">
                        <view class="q-yuedu-stem">
                            <text class="q-yuedu-idx">{{ sIdx + 1 }}.</text>
                            <view v-if="subQ.stem" class="q-yuedu-text">
                                <rich-text :nodes="subQ.stem" />
                            </view>
                        </view>
                        <view :class="['q-yuedu-opts', { vertical: !subQ.horizontal }]">
                            <view
                                v-for="(opt, oIdx) in subQ.options"
                                :key="oIdx"
                                :class="['q-yuedu-opt',
                                    {
                                        active: getYueDuAnswer(sIdx) === opt.label,
                                        correct: showYueDuCorrect(sIdx, opt.label),
                                        wrong: showYueDuWrong(sIdx, opt.label),
                                    }]"
                                @click="selectYueDuOption(sIdx, opt.label)"
                            >
                                <text class="q-yuedu-opt-label">{{ opt.label }}.</text>
                                <view class="q-yuedu-opt-value">
                                    <rich-text :nodes="opt.value" />
                                </view>
                            </view>
                        </view>
                    </view>
                </view>

                <!-- 完形填空 -->
                <view v-if="isWanXing && yueDuList.length" class="q-wanxing">
                    <view v-for="(subQ, sIdx) in yueDuList" :key="sIdx" class="q-wanxing-row">
                        <text class="q-wanxing-idx">{{ sIdx + 1 }}</text>
                        <view class="q-wanxing-opts">
                            <view
                                v-for="(opt, oIdx) in subQ.options"
                                :key="oIdx"
                                :class="['q-wanxing-opt',
                                    {
                                        active: getYueDuAnswer(sIdx) === opt.label,
                                        correct: showYueDuCorrect(sIdx, opt.label),
                                        wrong: showYueDuWrong(sIdx, opt.label),
                                    }]"
                                @click="selectYueDuOption(sIdx, opt.label)"
                            >
                                <text class="q-wanxing-opt-label">{{ opt.label }}</text>
                                <view class="q-wanxing-opt-value">
                                    <rich-text :nodes="opt.value" />
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
        </scroll-view>

        <!-- 中间分隔条 -->
        <view :class="['q-divider', { 'at-right': isLeftExpanded }]">
            <view class="q-divider-line"></view>
            <view class="q-fold-btn" @click="toggleLeftExpand">
                <view :class="['fold-arrow', { rotated: !isLeftExpanded }]"></view>
                <text>{{ isLeftExpanded ? '收起' : '展开' }}</text>
            </view>
        </view>

        <!-- 右侧答题 -->
        <scroll-view :class="['q-right', { collapsed: isLeftExpanded }]" scroll-y :show-scrollbar="false">
            <view class="q-right-inner">
                <!-- 批改结果 -->
                <view v-if="reportFlag" :class="['q-result', resultClass.class]">
                    <view class="q-result-icon">
                        <svg v-if="resultClass.class === 'success'" viewBox="0 0 24 24" fill="none">
                            <circle cx="12" cy="12" r="10" fill="#22C55E" />
                            <path d="m8 12 3 3 6-6" stroke="#FFFFFF" stroke-width="2.4"
                                stroke-linecap="round" stroke-linejoin="round" />
                        </svg>
                        <svg v-else-if="resultClass.class === 'wait'" viewBox="0 0 24 24" fill="none">
                            <circle cx="12" cy="12" r="10" fill="#F59E0B" />
                            <path d="M12 7v6M12 16v1" stroke="#FFFFFF" stroke-width="2"
                                stroke-linecap="round" />
                        </svg>
                        <svg v-else viewBox="0 0 24 24" fill="none">
                            <circle cx="12" cy="12" r="10" fill="#EF4444" />
                            <path d="m9 9 6 6m0-6-6 6" stroke="#FFFFFF" stroke-width="2.4"
                                stroke-linecap="round" />
                        </svg>
                    </view>
                    <view class="q-result-text">
                        <text class="t1">我的答案</text>
                        <text class="t2">{{ resultClass.text }}</text>
                    </view>
                </view>

                <!-- 得分 -->
                <view v-if="reportFlag && (data?.score != null || data?.actualScore != null)" class="q-score">
                    <view class="q-score-bar"></view>
                    <text class="q-score-text">满分{{ data?.score }}分，实际得分{{ data?.actualScore }}分</text>
                </view>

                <view class="q-answer-area">
                    <!-- 单选 -->
                    <template v-if="questionType === 'single'">
                        <view class="opt-list">
                            <view
                                v-for="(option, oIdx) in optionList"
                                :key="oIdx"
                                :class="['opt', {
                                    active: isSelected(option.key),
                                    correct: showCorrect(option.key),
                                    wrong: showWrong(option.key),
                                }]"
                                @click="selectOption(option.key)"
                            >
                                <view class="opt-key">{{ option.key }}</view>
                                <view class="opt-value">
                                    <rich-text :nodes="option.value" />
                                </view>
                            </view>
                        </view>
                    </template>

                    <!-- 多选 -->
                    <template v-else-if="questionType === 'multiple'">
                        <view class="opt-list">
                            <view
                                v-for="(option, oIdx) in optionList"
                                :key="oIdx"
                                :class="['opt multi', {
                                    active: isMultiSelected(option.key),
                                    correct: showCorrect(option.key),
                                    wrong: showMultiWrong(option.key),
                                }]"
                                @click="selectMultiOption(option.key)"
                            >
                                <view class="opt-key">{{ option.key }}</view>
                                <view class="opt-value">
                                    <rich-text :nodes="option.value" />
                                </view>
                            </view>
                        </view>
                    </template>

                    <!-- 判断 -->
                    <template v-else-if="questionType === 'judgment'">
                        <view class="judge-list">
                            <view
                                :class="['judge', {
                                    active: submitAnswer === '对' || submitAnswer === 'A',
                                    correct: showJudgmentCorrect('对'),
                                    wrong: showJudgmentWrong('对'),
                                }]"
                                @click="selectJudgment('对')"
                            >
                                <view class="judge-icon correct">
                                    <svg viewBox="0 0 24 24" fill="none">
                                        <path d="m6 12 4 4 8-8" stroke="#FFFFFF" stroke-width="3"
                                            stroke-linecap="round" stroke-linejoin="round" />
                                    </svg>
                                </view>
                                <text>正确</text>
                            </view>
                            <view
                                :class="['judge', {
                                    active: submitAnswer === '错' || submitAnswer === 'B',
                                    correct: showJudgmentCorrect('错'),
                                    wrong: showJudgmentWrong('错'),
                                }]"
                                @click="selectJudgment('错')"
                            >
                                <view class="judge-icon wrong">
                                    <svg viewBox="0 0 24 24" fill="none">
                                        <path d="m7 7 10 10M17 7 7 17" stroke="#FFFFFF" stroke-width="3"
                                            stroke-linecap="round" />
                                    </svg>
                                </view>
                                <text>错误</text>
                            </view>
                        </view>
                    </template>

                    <!-- 填空 -->
                    <template v-else-if="questionType === 'input'">
                        <view class="fill-area">
                            <view v-for="i in fillBlankNum" :key="i" class="fill-item">
                                <text class="fill-label">第{{ i }}空</text>
                                <input
                                    class="fill-input"
                                    :value="getInputValue(i - 1)"
                                    :disabled="!!reportFlag"
                                    placeholder="请输入答案"
                                    placeholder-class="fill-input-ph"
                                    @input="onInputChange($event, i - 1)"
                                />
                            </view>
                        </view>
                    </template>

                    <!-- 图片上传题 -->
                    <template v-else>
                        <view class="upload-area">
                            <view v-if="!reportFlag" class="upload-tip">
                                <view class="tip-icon">
                                    <svg viewBox="0 0 16 16" fill="none">
                                        <path d="M2 8a6 6 0 1 1 12 0 6 6 0 0 1-12 0z" stroke="#D97706"
                                            stroke-width="1.5" />
                                        <path d="M8 5v3M8 10.5v.5" stroke="#D97706" stroke-width="1.6"
                                            stroke-linecap="round" />
                                    </svg>
                                </view>
                                <text>请将答案写在纸上，拍照上传（最多3张）</text>
                            </view>

                            <view v-if="displayPicList.length" class="pic-list">
                                <view
                                    v-for="(pic, pIdx) in displayPicList"
                                    :key="pIdx"
                                    class="pic-item"
                                >
                                    <image
                                        v-if="!reportFlag || pic.status === 'pass' || pic.status === 'unknown'"
                                        :src="pic.url"
                                        mode="aspectFill"
                                        @click="previewDisplayPicList(pIdx)"
                                    />
                                    <view v-else-if="pic.status === 'pending'" class="pic-audit-pending">
                                        <text>{{ pic.statusText || '待复核' }}</text>
                                    </view>
                                    <view v-else-if="pic.status === 'fail'" class="pic-audit-fail">
                                        <text>{{ pic.statusText || '未通过审核' }}</text>
                                    </view>
                                    <view v-if="!reportFlag" class="del-btn" @click.stop="deletePic(pic.url)">
                                        <image class="del-icon" src="/static/image/svg/del.svg" mode="aspectFit" />
                                    </view>
                                </view>
                                <view
                                    v-if="!reportFlag && displayPicList.length < 3"
                                    class="add-btn"
                                    @click="chooseImage"
                                >
                                    <view class="add-plus"></view>
                                    <text>添加</text>
                                </view>
                            </view>
                            <view v-if="reportFlag && mediaAuditIssueTip" class="audit-tip fail">
                                <text>{{ mediaAuditIssueTip }}</text>
                            </view>
                            <view v-else-if="!reportFlag && !displayPicList.length" class="upload-btn" @click="chooseImage">
                                <view class="upload-camera">
                                    <svg viewBox="0 0 24 24" fill="none">
                                        <path d="M3 8a2 2 0 0 1 2-2h2l2-2h6l2 2h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8z"
                                            stroke="#FFFFFF" stroke-width="1.6" />
                                        <circle cx="12" cy="13" r="3" stroke="#FFFFFF" stroke-width="1.6" />
                                    </svg>
                                </view>
                                <text>拍照上传答案</text>
                            </view>
                            <view v-else-if="reportFlag && !picList.length" class="empty-tip">
                                <text>未作答</text>
                            </view>
                        </view>
                    </template>
                </view>

                <!-- 报告：参考答案/解析/AI -->
                <template v-if="reportFlag">
                    <view v-if="data?.answerHtml || data?.answer" class="ans-card">
                        <view class="ans-card-title">
                            <view class="ans-card-bar"></view>
                            <text>参考答案</text>
                        </view>
                        <view class="ans-card-body">
                            <rich-text :nodes="filterTitle(data?.answerHtml || data?.answer)" />
                        </view>
                    </view>

                    <view
                        v-if="(data?.explanation || data?.titleAnalyze) || data?.titleAnalyzePicture"
                        class="ans-card"
                    >
                        <view class="ans-card-title">
                            <view class="ans-card-bar"></view>
                            <text>解析</text>
                        </view>
                        <view v-if="data?.explanation || data?.titleAnalyze" class="ans-card-body">
                            <rich-text :nodes="filterTitle(data?.explanation || data?.titleAnalyze)" />
                        </view>
                        <view v-if="data.titleAnalyzePicture" class="ans-card-body pic">
                            <image
                                v-for="(pic, pIdx) in data.titleAnalyzePicture.split(',')"
                                :key="pIdx"
                                :src="pic"
                                mode="widthFix"
                                @click="previewAnalyzeImage(pic)"
                            />
                        </view>
                    </view>

                    <view v-if="data?.aiAnswer != null" class="ans-card ai">
                        <view class="ans-card-title">
                            <view class="ans-card-bar ai"></view>
                            <text>AI 答案</text>
                        </view>
                        <view class="ans-card-body">
                            <rich-text :nodes="filterTitle(typeof data.aiAnswer === 'string' ? data.aiAnswer : String(data.aiAnswer))" />
                        </view>
                    </view>

                    <view v-if="data?.aiAnalyze != null" class="ans-card ai">
                        <view class="ans-card-title">
                            <view class="ans-card-bar ai"></view>
                            <text>AI 点评</text>
                        </view>
                        <view class="ans-card-body">
                            <rich-text :nodes="filterTitle(typeof data.aiAnalyze === 'string' ? data.aiAnalyze : String(data.aiAnalyze))" />
                        </view>
                    </view>
                </template>
            </view>
        </scroll-view>

        <!-- 图片裁剪 -->
        <ImageCropper
            :visible="showCropper"
            :imageSrc="cropperImageSrc"
            :outputWidth="750"
            :outputHeight="750"
            @update:visible="showCropper = $event"
            @confirm="handleCropConfirm"
            @cancel="handleCropCancel"
        />
    </view>
</template>

<script setup lang="ts">
import { ref, computed, watch, onUnmounted } from 'vue';
import { uploadFile, checkImage } from '@/api/upload';
import ImageCropper from '@/components/ImageCropper/index.vue';
import { formatQuestionHtml } from '@/utils/questionHtml';
import {
    getMediaAuditInfoForImage,
    getQuestionTitleId,
    type MediaAuditStatus,
} from '@/utils/mediaAudit';
import { getWxOpenid } from '@/utils/wxOpenid';

const props = defineProps<{
    data?: any;
    idx: number;
    total: number;
    resourceType?: string;
    reportFlag: 0 | 1;
    subjectId?: string;
    recordId?: string;
}>();

const emit = defineEmits(['submit', 'cropper-visible-change']);

/* ============== 音频 ============== */
const isAudioPlay = ref(false);
let audioContext: any = null;

/* ============== 左侧展开 ============== */
const isLeftExpanded = ref(false);
const toggleLeftExpand = () => {
    isLeftExpanded.value = !isLeftExpanded.value;
};

/* ============== 题目图片提取 ============== */
const titleImages = computed(() => {
    const title = stemText.value || '';
    const pidTitle = props.data?.pidTitle || '';
    const allTitle = pidTitle + title;
    const imgRegex = /<img[^>]*\s*src=["']([^"']+)["'][^>]*\/?>/gi;
    const images: string[] = [];
    let match;
    while ((match = imgRegex.exec(allTitle)) !== 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;
});

const previewTitleImage = (index: number) => {
    uni.previewImage({
        urls: titleImages.value,
        current: titleImages.value[index],
    });
};

/* ============== 题目过滤 ============== */
const renderQuestionHtml = (title?: string, cidx?: number | string, options?: { stripImages?: boolean }) => {
    if (!title) return '';
    let html = formatQuestionHtml(title, options);
    if (cidx !== undefined) {
        html = `(${Number(cidx) + 1})${html}`;
    }
    return html;
};

const filterTitleWithoutImages = (title?: string, cidx?: number | string) => {
    return renderQuestionHtml(title, cidx, { stripImages: true });
};

const parseJsonArray = (raw: any) => {
    if (Array.isArray(raw)) return raw;
    if (typeof raw !== 'string') return [];
    try {
        const parsed = JSON.parse(raw);
        return Array.isArray(parsed) ? parsed : [];
    } catch {
        return [];
    }
};

const stemText = computed(() => {
    const data = props.data;
    if (!data) return '';
    if (data.stemType === 3) {
        return data.stemHtml || data.titleMu || data.title || data.stem || '';
    }
    return data.stemHtml || data.titleMu || data.title || data.stem || '';
});

/* ============== 答案 ============== */
const submitAnswer = ref('');
const submitAnswerPic = ref('');

watch(
    () => props.data?.id || props.data?.itemId,
    () => {
        submitAnswer.value = props.data?.submitAnswer || '';
        submitAnswerPic.value = props.data?.submitAnswerPic || '';
        if (audioContext) {
            audioContext.stop();
            isAudioPlay.value = false;
        }
    },
    { immediate: true },
);

/* ============== 选项 ============== */
const optionList = computed(() => {
    const data = props.data;
    const optionHtml = parseJsonArray(data?.optionHtml);
    let raw = optionHtml.length
        ? optionHtml
        : data?.optionsMu != null
            ? data.optionsMu
            : data?.options != null
                ? data.options
                : data?.optionList != null
                    ? data.optionList
                    : null;

    if (typeof raw === 'string') {
        try { raw = JSON.parse(raw); } catch { raw = null; }
    }
    const normalized = Array.isArray(raw) ? (normalizeOptionsFromOptionList(raw) ?? raw) : raw ? [raw] : [];
    const list = Array.isArray(normalized) ? normalized : [];
    if (list.length === 0) return [];

    return list.map((item: any, idx: number) => {
        let value = '';
        if (typeof item === 'string') {
            value = String(item || '');
        } else {
            const v = item?.html ?? item?.value ?? item?.optionValue ?? item?.content ?? '';
            value = v != null && v !== '' ? String(v) : '';
        }
        value = formatQuestionHtml(value);
        return {
            key:
                typeof item === 'string'
                    ? String.fromCharCode(65 + idx)
                    : (item.key || item.optionKey || item.label || String.fromCharCode(65 + idx)),
            value,
        };
    });
});

const fillBlankNum = computed(() => props.data?.fillBlankNum || 0);

/* ============== 阅读 / 完形 ============== */
function toSimpleOptions(list: any[]) {
    return list.map((item: any, idx: number) => {
        let value = item;
        if (typeof item === 'object' && item !== null) {
            value = item.html || item.value || item.optionValue || item.content || '';
        }
        return {
            label: String.fromCharCode(65 + idx),
            value: value ?? '',
        };
    });
}

function normalizeOptionsFromOptionList(optionList: any[]) {
    if (!Array.isArray(optionList) || !optionList.length) return undefined;
    let list = optionList;
    while (Array.isArray(list) && list.length === 1 && Array.isArray(list[0])) {
        list = list[0];
    }
    if (
        list.every((i: any) => Array.isArray(i)) &&
        list.some((i: any) => Array.isArray(i) && i.length)
    ) {
        return (list as any[]).map((sub: any[]) => ({ options: toSimpleOptions(sub) }));
    }
    if (list.every((i: any) => typeof i === 'string')) {
        return toSimpleOptions(list as any[]);
    }
    return list;
}

const rawParsedOptions = computed(() => {
    const data = props.data;
    if (data?.stemType === 3) {
        const stems = parseJsonArray(data.stemSqs);
        const opts = parseJsonArray(data.optionSqs);
        const maxLen = Math.max(stems.length, opts.length);
        if (maxLen === 0) return [];
        return Array.from({ length: maxLen }, (_, idx) => ({
            stem: stems[idx] || '',
            options: Array.isArray(opts[idx]) ? toSimpleOptions(opts[idx]) : [],
        }));
    }

    const optionHtml = parseJsonArray(data?.optionHtml);
    if (optionHtml.length) {
        return [optionHtml.map((item: any) => item?.html || item?.value || item?.optionValue || '')];
    }

    let raw = data?.optionsMu != null ? data.optionsMu
        : data?.options != null ? data.options
            : data?.optionList != null ? data.optionList : null;
    if (typeof raw === 'string') {
        try { raw = JSON.parse(raw); } catch { raw = null; }
    }
    if (Array.isArray(raw)) {
        return normalizeOptionsFromOptionList(raw) ?? raw;
    }
    return [];
});

const isYueDu = computed(() => {
    const list = rawParsedOptions.value;
    if (!list.length) return false;
    return list.some((item: any) => item?.options && item?.stem);
});

const isWanXing = computed(() => {
    if (isYueDu.value) return false;
    const list = rawParsedOptions.value;
    if (!list.length) return false;
    return list.some((item: any) => item?.options && !item?.stem);
});

const yueDuList = computed(() => {
    if (!isYueDu.value && !isWanXing.value) return [];
    return rawParsedOptions.value.map((item: any, idx: number) => {
        const rawSubOpts = Array.isArray(item.options) ? item.options : [];
        const subOpts = rawSubOpts.map((opt: any, oIdx: number) => {
            let v = typeof opt === 'string' ? opt : (opt?.html ?? opt?.value ?? opt?.optionValue ?? opt?.content ?? '');
            v = v != null ? String(v) : '';
            v = formatQuestionHtml(v);
            return {
                label:
                    typeof opt === 'string'
                        ? String.fromCharCode(65 + oIdx)
                        : opt?.label || opt?.optionKey || String.fromCharCode(65 + oIdx),
                value: v,
            };
        });
        let stem = '';
        if (item.stem) {
            stem = String(item.stem);
            stem = formatQuestionHtml(stem);
        }
        let horizontal = false;
        if (subOpts.length > 0) {
            const maxLen = Math.max(...subOpts.map((o: any) => String(o.value || '').replace(/<[^>]*>/g, '').length));
            horizontal = maxLen < 10;
        }
        return { index: idx, stem, options: subOpts, horizontal };
    });
});

const questionType = computed(() => {
    const data = props.data;
    if (!data) return 'other';
    if (isYueDu.value) return 'yuedu';
    if (isWanXing.value) return 'wanxing';
    if (['判断', '判断题'].includes(data.titleChannelTypeName)) return 'judgment';
    if (data.titleChannelTypeName === '多选题') return 'multiple';
    if (data.fillBlankNum) return 'input';
    if (optionList.value.length > 0) return 'single';
    return 'other';
});

const resultClass = computed(() => {
    const data = props.data;
    if (!data) return { class: 'info', text: '0分', icon: '' };
    if (data.titleStatus === 2) {
        return { class: 'wait', text: '待批改', icon: '' };
    }
    if (data.correctResult || data.markFlag) {
        return { class: 'success', text: '答对啦', icon: 'emoji_success' };
    }
    if (data?.actualScore !== 0 && data?.actualScore !== data?.score) {
        return { class: 'info', text: '部分正确', icon: '' };
    }
    const hasAnswer = data?.submitAnswer || data?.submitAnswerPic;
    return {
        class: 'error',
        text: hasAnswer ? '答错了' : '未作答',
        icon: 'emoji_fail',
    };
});

const filterTitle = (title?: string, cidx?: number | string) => {
    return renderQuestionHtml(title, cidx);
};

/* ============== 单选 ============== */
const isSelected = (key: string) => submitAnswer.value === key;

const getCorrectAnswer = () => {
    return props.data?.answerHtml || props.data?.answerSqs || props.data?.answer || '';
};

const showCorrect = (key: string) => {
    if (!props.reportFlag) return false;
    return getCorrectAnswer().includes(key);
};

const showWrong = (key: string) => {
    if (!props.reportFlag) return false;
    return submitAnswer.value === key && !getCorrectAnswer().includes(key);
};

const selectOption = (key: string) => {
    if (props.reportFlag) return;
    submitAnswer.value = key;
    emit('submit', { submitAnswer: key, toNext: true });
};

/* ============== 多选 ============== */
const isMultiSelected = (key: string) => submitAnswer.value.includes(key);

const selectMultiOption = (key: string) => {
    if (props.reportFlag) return;
    const answers = submitAnswer.value
        .split(',')
        .flatMap((item) => item.split(''))
        .map((item) => item.trim())
        .filter(Boolean);
    const idx = answers.indexOf(key);
    if (idx !== -1) {
        answers.splice(idx, 1);
    } else {
        answers.push(key);
    }
    submitAnswer.value = answers.sort().join(',');
    emit('submit', { submitAnswer: submitAnswer.value });
};

const showMultiWrong = (key: string) => {
    if (!props.reportFlag) return false;
    return isMultiSelected(key) && !getCorrectAnswer().includes(key);
};

/* ============== 判断 ============== */
const selectJudgment = (value: string) => {
    if (props.reportFlag) return;
    submitAnswer.value = value;
    emit('submit', { submitAnswer: value, toNext: true });
};

const showJudgmentCorrect = (value: string) => {
    if (!props.reportFlag) return false;
    const answer = getCorrectAnswer();
    return answer.includes(value) || (value === '对' && answer.includes('A')) || (value === '错' && answer.includes('B'));
};

const showJudgmentWrong = (value: string) => {
    if (!props.reportFlag) return false;
    if (submitAnswer.value !== value) return false;
    return !showJudgmentCorrect(value);
};

/* ============== 阅读/完形答题 ============== */
const yueDuAnswerList = computed(() => {
    if (!submitAnswer.value) return [];
    return submitAnswer.value.split(',');
});

const getYueDuAnswer = (sIdx: number): string => yueDuAnswerList.value[sIdx] || '';

const selectYueDuOption = (sIdx: number, key: string) => {
    if (props.reportFlag) return;
    const answers = [...yueDuAnswerList.value];
    while (answers.length <= sIdx) answers.push('');
    answers[sIdx] = key;
    submitAnswer.value = answers.join(',');
    emit('submit', { submitAnswer: submitAnswer.value });
};

const correctAnswerList = computed(() => {
    const raw = props.data?.answerSqs || props.data?.answerHtml || props.data?.answer;
    if (!raw) return [];
    if (Array.isArray(raw)) return raw.map(String);
    if (typeof raw === 'string') {
        try {
            const parsed = JSON.parse(raw);
            if (Array.isArray(parsed)) return parsed.map(String);
        } catch { /* not JSON */ }
        return raw.split(',').map((s: string) => s.trim());
    }
    return [];
});

const showYueDuCorrect = (sIdx: number, key: string): boolean => {
    if (!props.reportFlag) return false;
    return correctAnswerList.value[sIdx] === key;
};

const showYueDuWrong = (sIdx: number, key: string): boolean => {
    if (!props.reportFlag) return false;
    const myAnswer = yueDuAnswerList.value[sIdx];
    const correctAnswer = correctAnswerList.value[sIdx];
    return myAnswer === key && myAnswer !== correctAnswer;
};

/* ============== 填空 ============== */
const getInputValue = (idx: number) => {
    const answers = submitAnswer.value.split(',');
    return answers[idx] || '';
};

const onInputChange = (e: any, idx: number) => {
    const value = e.detail.value;
    const answers = submitAnswer.value.split(',');
    while (answers.length <= idx) answers.push('');
    answers[idx] = value;
    submitAnswer.value = answers.join(',');
    emit('submit', { submitAnswer: submitAnswer.value });
};

/* ============== 图片上传 ============== */
const picList = computed(() => {
    if (!submitAnswerPic.value) return [];
    return submitAnswerPic.value
        .split(',')
        .map((url: string) => url.replace(/http:\/\//gi, 'https://').trim())
        .filter(Boolean);
});

interface PicDisplayItem {
    url: string;
    status: MediaAuditStatus;
    labelText: string;
    statusText: string;
}

const displayPicList = computed((): PicDisplayItem[] => {
    const pics = picList.value;
    if (!props.reportFlag) {
        return pics.map((url) => ({
            url,
            status: 'unknown' as MediaAuditStatus,
            labelText: '',
            statusText: '',
        }));
    }

    const auditList = props.data?.mediaAuditList;
    return pics.map((url) => {
        const info = getMediaAuditInfoForImage(url, auditList);
        return {
            url,
            status: info.status,
            labelText: info.labelText,
            statusText: info.statusText,
        };
    });
});

const mediaAuditIssueTip = computed(() => {
    if (!props.reportFlag || !picList.value.length) return '';

    const issues = displayPicList.value.filter(
        (item) => item.status === 'fail' || item.status === 'pending',
    );
    if (!issues.length) return '';

    const failItems = issues.filter((item) => item.status === 'fail');
    const pendingItems = issues.filter((item) => item.status === 'pending');

    const parts: string[] = [];
    if (failItems.length) {
        const labels = [...new Set(failItems.map((item) => item.labelText).filter(Boolean))];
        const labelPart = labels.length ? `（${labels.map((t) => `涉${t}`).join('、')}）` : '';
        parts.push(`${failItems.length} 张图片未通过内容审核${labelPart}`);
    }
    if (pendingItems.length) {
        const labels = [...new Set(pendingItems.map((item) => item.labelText).filter(Boolean))];
        const labelPart = labels.length ? `（${labels.join('、')}）` : '';
        parts.push(`${pendingItems.length} 张图片待人工复核${labelPart}`);
    }

    return parts.join('；');
});

const previewDisplayPicList = (index: number) => {
    const previewable = displayPicList.value.filter(
        (item) => !props.reportFlag || item.status === 'pass' || item.status === 'unknown',
    );
    if (!previewable.length) return;

    const current = displayPicList.value[index];
    if (!current || (props.reportFlag && current.status !== 'pass' && current.status !== 'unknown')) return;

    uni.previewImage({
        urls: previewable.map((item) => item.url),
        current: current.url,
    });
};

const showCropper = ref(false);
const cropperImageSrc = ref('');

watch(showCropper, (visible) => {
    emit('cropper-visible-change', visible);
});

const chooseImage = () => {
    const remain = 3 - picList.value.length;
    if (remain <= 0) {
        uni.showToast({ title: '最多上传3张图片', icon: 'none' });
        return;
    }
    uni.chooseImage({
        count: 1,
        sizeType: ['original'],
        sourceType: ['camera', 'album'],
        success: async (res) => {
            const filePath = res.tempFilePaths[0];
            cropperImageSrc.value = filePath;
            showCropper.value = true;
        },
        fail: (err) => {
            console.error('选择图片失败', err);
            uni.showToast({ title: '选择图片失败', icon: 'none' });
        },
    });
};

const handleCropConfirm = (filePath: string) => uploadImage(filePath);

const handleCropCancel = () => {
    showCropper.value = false;
    cropperImageSrc.value = '';
};

const uploadImage = async (filePath: string) => {
    uni.showLoading({ title: '上传中...' });
    try {
        const uploadRes: any = await uploadFile(filePath);
        const newUrl = uploadRes.url || uploadRes.filePath;
        const newList = [...picList.value, newUrl];
        submitAnswerPic.value = newList.join(',');
        emit('submit', { submitAnswerPic: submitAnswerPic.value });
        uni.hideLoading();

        // 上传成功后提交图片内容安全检测
        const titleId = getQuestionTitleId(props.data);
        const recordId = props.recordId || '';
        if (titleId && recordId && newUrl) {
            getWxOpenid()
                .then((openid) => checkImage({
                    openid,
                    recordId,
                    titleId,
                    imageUrl: newUrl,
                }))
                .catch((err) => {
                    console.warn('[Question] checkImage failed', err);
                });
        }
    } catch (err: any) {
        uni.hideLoading();
        if (Number(err?.code) === 401) return;
        uni.showToast({ title: err?.message || '上传失败', icon: 'none' });
    }
};

const deletePic = (url: string) => {
    const newList = picList.value.filter((pic: string) => pic !== url);
    submitAnswerPic.value = newList.join(',');
    emit('submit', { submitAnswerPic: submitAnswerPic.value });
};

const previewAnalyzeImage = (url: string) => {
    uni.previewImage({
        urls: props.data.titleAnalyzePicture.split(','),
        current: url,
    });
};

/* ============== 音频 ============== */
const playAudio = () => {
    if (!props.data?.voiceUrl) return;
    if (!audioContext) {
        audioContext = uni.createInnerAudioContext();
        audioContext.onPlay(() => { isAudioPlay.value = true; });
        audioContext.onPause(() => { isAudioPlay.value = false; });
        audioContext.onEnded(() => { isAudioPlay.value = false; });
        audioContext.onError(() => { isAudioPlay.value = false; });
    }
    if (isAudioPlay.value) {
        audioContext.pause();
    } else {
        audioContext.src = props.data.voiceUrl;
        audioContext.play();
    }
};

onUnmounted(() => {
    if (audioContext) {
        audioContext.destroy();
        audioContext = null;
    }
});
</script>

<style lang="scss" scoped>
.q-item {
    width: 100%;
    height: 100%;
    display: flex;
    position: relative;
    background: linear-gradient(135deg, #fafbff 0%, #ffffff 40%, #ffffff 60%, #f5f7ff 100%);
    border-radius: 18rpx;
    overflow: hidden;
    box-shadow:
        0 12rpx 32rpx rgba(99, 102, 241, 0.12),
        inset 0 -4rpx 0 rgba(199, 210, 254, 0.5);
}

/* 中间分隔条 */
.q-divider {
    position: absolute;
    left: 56%;
    top: 0;
    bottom: 0;
    width: 48rpx;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    z-index: 10;
    transition: left 300ms ease;
    pointer-events: none;

    /* 柔化背景过渡层 - 消除两侧背景断裂感 */
    &::before {
        content: '';
        position: absolute;
        left: 50%;
        top: 0;
        bottom: 0;
        width: 160rpx;
        transform: translateX(-50%);
        background: linear-gradient(
            to right,
            transparent 0%,
            rgba(199, 210, 254, 0.08) 30%,
            rgba(165, 180, 252, 0.12) 50%,
            rgba(199, 210, 254, 0.08) 70%,
            transparent 100%
        );
        pointer-events: none;
    }

    &.at-right {
        left: calc(100% - 24rpx);
    }
}

.q-divider-line {
    flex: 1;
    width: 2rpx;
    margin-top: 24rpx;
    background: linear-gradient(
        to bottom,
        transparent,
        #c7d2fe 10%,
        #c7d2fe 50%,
        #a5b4fc 50%,
        #c7d2fe 90%,
        transparent
    );
    opacity: 0.7;
    border-radius: 2rpx;
}

.q-fold-btn {
    pointer-events: auto;
    margin: 8rpx 0 16rpx;
    padding: 7rpx 4rpx;
    background: linear-gradient(180deg, #818cf8, #4f46e5);
    border-radius: 10rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4rpx;
    box-shadow:
        0 6rpx 12rpx rgba(79, 70, 229, 0.35),
        inset 0 -3rpx 0 rgba(0, 0, 0, 0.12);

    &:active {
        transform: scale(0.94);
    }

    text {
        font-size: 13rpx;
        color: #ffffff;
        writing-mode: vertical-lr;
        letter-spacing: 2rpx;
        font-weight: 600;
    }
}

.fold-arrow {
    width: 11rpx;
    height: 11rpx;
    border-left: 2rpx solid #ffffff;
    border-bottom: 2rpx solid #ffffff;
    transform: rotate(45deg);
    transition: transform 200ms ease;

    &.rotated {
        transform: rotate(-135deg);
    }
}

/* 左侧 */
.q-left {
    width: 58%;
    height: 100%;
    box-sizing: border-box;
    transition: width 300ms ease;
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, #fafbff 0%, #ffffff 60%, #f7f9ff 100%);

    /* 右侧边缘渐变过渡到分隔条 */
    &::after {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 60rpx;
        background: linear-gradient(
            to right,
            transparent,
            rgba(165, 180, 252, 0.06)
        );
        pointer-events: none;
        z-index: 1;
    }

    &.expanded {
        width: calc(100% - 48rpx);
    }
}

.q-left-inner {
    padding: 10rpx 28rpx 10rpx 12rpx;
}

.q-type {
    display: inline-flex;
    padding: 2rpx 8rpx;
    background: #eef2ff;
    border-radius: 999rpx;
    margin-bottom: 6rpx;

    text {
        font-size: 13rpx;
        color: #4f46e5;
        font-weight: 600;
    }
}

.q-pid,
.q-title {
    font-size: 18rpx;
    color: #312e81;
    line-height: 1.45;
    margin-bottom: 5rpx;

    :deep(image) {
        max-width: 100%;
        height: auto;
    }

    :deep(.fill-blank) {
        display: inline-block;
        min-width: 60rpx;
        height: 1em;
        border-bottom: 3rpx solid #4f46e5;
        margin: 0 6rpx;
        vertical-align: baseline;
    }

    :deep(.formula-text) {
        font-size: 24rpx;
        font-family: 'Times New Roman', 'STIXGeneral', Georgia, serif;
        font-style: italic;
        color: #1e1b4b;
        letter-spacing: 0.5rpx;
        vertical-align: baseline;
    }

    :deep(.formula-img) {
        max-width: 100%;
    }
}

.q-pid {
    padding: 7rpx 10rpx;
    background: #f5f7ff;
    border-radius: 12rpx;
    border-left: 4rpx solid #818cf8;
    color: #4338ca;
    font-size: 17rpx;
}

.q-images {
    margin: 12rpx 0;
    display: flex;
    flex-wrap: wrap;
    gap: 16rpx;

    image {
        max-width: 100%;
        border-radius: 16rpx;
        box-shadow:
            0 6rpx 12rpx rgba(99, 102, 241, 0.18),
            inset 0 -3rpx 0 rgba(199, 210, 254, 0.5);
    }
}

/* 音频 */
.q-voice {
    margin: 16rpx 0;
    display: inline-flex;
    align-items: center;
    gap: 12rpx;
}

.voice-btn {
    position: relative;
    width: 80rpx;
    height: 80rpx;
    border-radius: 50%;
    background: linear-gradient(180deg, #4ade80, #16a34a);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow:
        0 8rpx 16rpx rgba(22, 163, 74, 0.35),
        inset 0 -4rpx 0 rgba(0, 0, 0, 0.15);

    svg {
        width: 40rpx;
        height: 40rpx;
        position: relative;
        z-index: 1;
    }

    &:active {
        transform: scale(0.9);
    }

    &.playing .voice-wave {
        animation: voice-pulse 1.4s ease-out infinite;
    }
}

.voice-wave {
    position: absolute;
    inset: -8rpx;
    border-radius: 50%;
    border: 4rpx solid rgba(34, 197, 94, 0.45);
    opacity: 0;

    &.delay-1 { animation-delay: 0.4s !important; }
    &.delay-2 { animation-delay: 0.8s !important; }
}

@keyframes voice-pulse {
    0% { transform: scale(0.9); opacity: 0.8; }
    100% { transform: scale(1.6); opacity: 0; }
}

.voice-text {
    font-size: 22rpx;
    color: #16a34a;
    font-weight: 600;
}

/* 子题 */
.q-children {
    margin-top: 16rpx;
    display: flex;
    flex-direction: column;
    gap: 12rpx;
}

.q-child {
    font-size: 24rpx;
    color: #475569;
    line-height: 1.7;
    padding: 12rpx 16rpx;
    background: #f5f7ff;
    border-radius: 12rpx;
}

/* 阅读理解 */
.q-yuedu {
    margin-top: 20rpx;
    display: flex;
    flex-direction: column;
    gap: 16rpx;
}

.q-yuedu-item {
    padding: 16rpx 18rpx;
    background: #f5f7ff;
    border-radius: 16rpx;
    border-left: 6rpx solid #818cf8;
}

.q-yuedu-stem {
    display: flex;
    align-items: flex-start;
    gap: 8rpx;
    margin-bottom: 10rpx;

    .q-yuedu-idx {
        font-size: 24rpx;
        font-weight: 800;
        color: #4f46e5;
        flex-shrink: 0;
    }

    .q-yuedu-text {
        flex: 1;
        font-size: 24rpx;
        color: #312e81;
        line-height: 1.6;

        :deep(image) { max-width: 100%; height: auto; }
        :deep(.formula-text) {
            font-family: 'Times New Roman', serif;
            font-style: italic;
            color: #1e1b4b;
        }
    }
}

.q-yuedu-opts {
    padding-left: 24rpx;
    display: flex;
    flex-wrap: wrap;
    gap: 8rpx 20rpx;

    &.vertical {
        flex-direction: column;
        gap: 8rpx;
    }
}

.q-yuedu-opt {
    display: flex;
    align-items: flex-start;
    gap: 6rpx;
    padding: 6rpx 12rpx;
    border-radius: 10rpx;
    transition: background 150ms ease;

    .q-yuedu-opt-label {
        font-size: 22rpx;
        font-weight: 700;
        color: #6366f1;
        flex-shrink: 0;
    }

    .q-yuedu-opt-value {
        font-size: 22rpx;
        color: #312e81;

        :deep(image) { max-width: 100%; height: auto; }
    }

    &.active {
        background: #c7d2fe;

        .q-yuedu-opt-label, .q-yuedu-opt-value { color: #312e81; }
    }

    &.correct {
        background: #dcfce7;

        .q-yuedu-opt-label, .q-yuedu-opt-value { color: #15803d; }
    }

    &.wrong {
        background: #fee2e2;

        .q-yuedu-opt-label, .q-yuedu-opt-value { color: #b91c1c; }
    }
}

/* 完形 */
.q-wanxing {
    margin-top: 16rpx;
    display: flex;
    flex-direction: column;
    gap: 10rpx;
}

.q-wanxing-row {
    display: flex;
    align-items: flex-start;
    gap: 12rpx;
}

.q-wanxing-idx {
    width: 36rpx;
    height: 36rpx;
    flex-shrink: 0;
    background: linear-gradient(180deg, #818cf8, #4f46e5);
    color: #ffffff;
    border-radius: 10rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20rpx;
    font-weight: 700;
    box-shadow: 0 3rpx 6rpx rgba(79, 70, 229, 0.3);
}

.q-wanxing-opts {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    gap: 6rpx 14rpx;
}

.q-wanxing-opt {
    display: flex;
    align-items: center;
    gap: 4rpx;
    padding: 4rpx 10rpx;
    border-radius: 8rpx;
    transition: background 150ms ease;

    .q-wanxing-opt-label {
        font-size: 22rpx;
        font-weight: 700;
        color: #6366f1;
    }

    .q-wanxing-opt-value {
        font-size: 22rpx;
        color: #312e81;
    }

    &.active {
        background: #c7d2fe;
    }

    &.correct {
        background: #dcfce7;

        .q-wanxing-opt-label, .q-wanxing-opt-value { color: #15803d; }
    }

    &.wrong {
        background: #fee2e2;

        .q-wanxing-opt-label, .q-wanxing-opt-value { color: #b91c1c; }
    }
}

/* 右侧答题 */
.q-right {
    width: 42%;
    height: 100%;
    box-sizing: border-box;
    transition: width 300ms ease, opacity 200ms ease;
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 55%, #f7f9ff 100%);

    /* 左侧边缘渐变过渡到分隔条 */
    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        width: 40rpx;
        background: linear-gradient(
            to right,
            rgba(165, 180, 252, 0.06),
            transparent
        );
        pointer-events: none;
        z-index: 1;
    }

    &.collapsed {
        width: 0;
        padding: 0;
        opacity: 0;
        overflow: hidden;
        pointer-events: none;

        &::before {
            display: none;
        }
    }
}

.q-right-inner {
    padding: 10rpx 12rpx 10rpx 28rpx;
}

/* 批改结果 */
.q-result {
    display: flex;
    align-items: center;
    gap: 16rpx;
    padding: 16rpx 20rpx;
    border-radius: 20rpx;
    margin-bottom: 16rpx;

    &.success {
        background: linear-gradient(135deg, #dcfce7, #bbf7d0);
    }

    &.error {
        background: linear-gradient(135deg, #fee2e2, #fecaca);
    }

    &.wait {
        background: linear-gradient(135deg, #fef3c7, #fde68a);
    }

    &.info {
        background: linear-gradient(135deg, #dbeafe, #bfdbfe);
    }

    .q-result-icon {
        width: 56rpx;
        height: 56rpx;
        flex-shrink: 0;

        svg {
            width: 100%;
            height: 100%;
            filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.15));
        }
    }

    .q-result-text {
        display: flex;
        flex-direction: column;

        .t1 {
            font-size: 20rpx;
            color: #6366f1;
            opacity: 0.7;
        }

        .t2 {
            font-size: 30rpx;
            font-weight: 800;
            color: #312e81;
        }
    }
}

/* 得分 */
.q-score {
    display: flex;
    align-items: center;
    gap: 10rpx;
    padding: 10rpx 20rpx;
    margin-bottom: 16rpx;
    background: #f5f7ff;
    border-radius: 14rpx;

    &-bar {
        width: 6rpx;
        height: 22rpx;
        border-radius: 3rpx;
        background: linear-gradient(180deg, #818cf8, #4f46e5);
        flex-shrink: 0;
    }

    &-text {
        font-size: 20rpx;
        color: #4338ca;
        font-weight: 600;
    }
}

/* 答题区 */
.q-answer-area {
    margin-bottom: 8rpx;
}

/* 选项 */
.opt-list {
    display: flex;
    flex-direction: column;
    gap: 7rpx;
}

.opt {
    display: flex;
    align-items: center;
    padding: 7rpx 9rpx;
    background: #ffffff;
    border-radius: 12rpx;
    border: 2rpx solid #e0e7ff;
    transition: all 200ms ease;
    box-shadow:
        0 4rpx 8rpx rgba(99, 102, 241, 0.08),
        inset 0 -3rpx 0 rgba(199, 210, 254, 0.4);

    &:active {
        transform: scale(0.98);
    }

    .opt-key {
        width: 30rpx;
        height: 30rpx;
        background: #f5f7ff;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 16rpx;
        font-weight: 800;
        color: #6366f1;
        margin-right: 7rpx;
        flex-shrink: 0;
        transition: all 200ms ease;
    }

    .opt-value {
        flex: 1;
        font-size: 17rpx;
        color: #312e81;
        line-height: 1.45;

        :deep(image) { max-width: 100%; height: auto; }
        :deep(.formula-text) {
            font-family: 'Times New Roman', serif;
            font-style: italic;
            color: #1e1b4b;
            font-size: 24rpx;
        }
    }

    &.active {
        border-color: #4f46e5;
        background: linear-gradient(135deg, #eef2ff, #e0e7ff);

        .opt-key {
            background: linear-gradient(180deg, #818cf8, #4f46e5);
            color: #ffffff;
            box-shadow: 0 4rpx 10rpx rgba(79, 70, 229, 0.3);
        }
    }

    &.correct {
        border-color: #16a34a;
        background: linear-gradient(135deg, #dcfce7, #bbf7d0);

        .opt-key {
            background: linear-gradient(180deg, #4ade80, #16a34a);
            color: #ffffff;
            box-shadow: 0 4rpx 10rpx rgba(22, 163, 74, 0.3);
        }
    }

    &.wrong {
        border-color: #dc2626;
        background: linear-gradient(135deg, #fee2e2, #fecaca);

        .opt-key {
            background: linear-gradient(180deg, #f87171, #dc2626);
            color: #ffffff;
            box-shadow: 0 4rpx 10rpx rgba(220, 38, 38, 0.3);
        }
    }
}

/* 判断 */
.judge-list {
    display: flex;
    justify-content: center;
    gap: 12rpx;
    padding: 5rpx 0;
}

.judge {
    flex: 1;
    max-width: 150rpx;
    padding: 12rpx 8rpx;
    background: #ffffff;
    border-radius: 15rpx;
    border: 2rpx solid #e0e7ff;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8rpx;
    transition: all 200ms ease;
    box-shadow:
        0 6rpx 12rpx rgba(99, 102, 241, 0.1),
        inset 0 -4rpx 0 rgba(199, 210, 254, 0.5);

    &:active {
        transform: scale(0.96);
    }

    .judge-icon {
        width: 42rpx;
        height: 42rpx;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;

        svg { width: 32rpx; height: 32rpx; }

        &.correct {
            background: linear-gradient(180deg, #4ade80, #16a34a);
            box-shadow: 0 6rpx 12rpx rgba(22, 163, 74, 0.3);
        }

        &.wrong {
            background: linear-gradient(180deg, #f87171, #dc2626);
            box-shadow: 0 6rpx 12rpx rgba(220, 38, 38, 0.3);
        }
    }

    text {
        font-size: 18rpx;
        font-weight: 700;
        color: #312e81;
    }

    &.active {
        background: linear-gradient(135deg, #eef2ff, #e0e7ff);
        border-color: #4f46e5;
    }

    &.correct {
        border-color: #16a34a;
        background: linear-gradient(135deg, #dcfce7, #bbf7d0);

        .judge-icon.correct {
            box-shadow: 0 6rpx 12rpx rgba(22, 163, 74, 0.3);
        }
    }

    &.wrong {
        border-color: #dc2626;
        background: linear-gradient(135deg, #fee2e2, #fecaca);

        .judge-icon.wrong {
            box-shadow: 0 6rpx 12rpx rgba(220, 38, 38, 0.3);
        }
    }
}

/* 填空 */
.fill-area {
    display: flex;
    flex-direction: column;
    gap: 10rpx;
}

.fill-item {
    display: flex;
    align-items: center;
    gap: 14rpx;
}

.fill-label {
    flex-shrink: 0;
    padding: 3rpx 10rpx;
    background: linear-gradient(135deg, #eef2ff, #e0e7ff);
    border-radius: 999rpx;
    font-size: 17rpx;
    font-weight: 700;
    color: #4f46e5;
}

.fill-input {
    flex: 1;
    height: 46rpx;
    padding: 0 14rpx;
    background: #f5f7ff;
    border: 3rpx solid #e0e7ff;
    border-radius: 12rpx;
    font-size: 18rpx;
    color: #312e81;

    &:focus {
        border-color: #818cf8;
    }
}

.fill-input-ph {
    color: #94a3b8;
    font-size: 22rpx;
}

/* 上传 */
.upload-area {
    display: flex;
    flex-direction: column;
    gap: 8rpx;
}

.upload-tip {
    display: flex;
    align-items: center;
    gap: 8rpx;
    padding: 6rpx 9rpx;
    background: linear-gradient(135deg, #fef3c7, #fde68a);
    border-radius: 10rpx;

    .tip-icon {
        width: 22rpx;
        height: 22rpx;
        flex-shrink: 0;

        svg { width: 100%; height: 100%; }
    }

    text {
        flex: 1;
        font-size: 15rpx;
        color: #92400e;
        line-height: 1.5;
    }
}

.pic-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10rpx;
}

.pic-item {
    position: relative;
    width: 90rpx;
    height: 90rpx;
    border-radius: 12rpx;
    overflow: hidden;
    background: #f5f7ff;
    box-shadow:
        0 4rpx 8rpx rgba(99, 102, 241, 0.18),
        inset 0 -3rpx 0 rgba(199, 210, 254, 0.5);

    image {
        width: 100%;
        height: 100%;
    }

    .del-btn {
        position: absolute;
        top: 4rpx;
        right: 4rpx;
        width: 38rpx;
        height: 38rpx;
        background: rgba(15, 23, 42, 0.65);
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;

        .del-icon {
            width: 24rpx;
            height: 24rpx;
        }
    }
}

.pic-audit-pending,
.pic-audit-fail {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;

    text {
        font-size: 18rpx;
        line-height: 1.3;
        text-align: center;
        padding: 0 6rpx;
    }
}

.pic-audit-pending {
    background: #f1f5f9;

    text {
        color: #64748b;
    }
}

.pic-audit-fail {
    background: #fef2f2;

    text {
        color: #b91c1c;
    }
}

.audit-tip {
    margin-top: 6rpx;
    padding: 6rpx 9rpx;
    border-radius: 10rpx;

    text {
        font-size: 15rpx;
        line-height: 1.5;
    }

    &.fail {
        background: #fef2f2;

        text {
            color: #b91c1c;
        }
    }
}

.add-btn {
    width: 90rpx;
    height: 90rpx;
    border-radius: 12rpx;
    background: #f5f7ff;
    border: 3rpx dashed #c7d2fe;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8rpx;

    .add-plus {
        position: relative;
        width: 36rpx;
        height: 36rpx;

        &::before, &::after {
            content: '';
            position: absolute;
            background: #6366f1;
            border-radius: 4rpx;
        }

        &::before {
            left: 50%;
            top: 0;
            width: 4rpx;
            height: 100%;
            transform: translateX(-50%);
        }

        &::after {
            top: 50%;
            left: 0;
            width: 100%;
            height: 4rpx;
            transform: translateY(-50%);
        }
    }

    text {
        font-size: 20rpx;
        color: #6366f1;
        font-weight: 600;
    }

    &:active {
        background: #eef2ff;
    }
}

.upload-btn {
    height: 84rpx;
    background: linear-gradient(180deg, #818cf8, #4f46e5);
    border-radius: 14rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8rpx;
    color: #ffffff;
    box-shadow:
        0 8rpx 18rpx rgba(79, 70, 229, 0.35),
        inset 0 -4rpx 0 rgba(0, 0, 0, 0.15);

    .upload-camera {
        width: 30rpx;
        height: 30rpx;

        svg { width: 100%; height: 100%; }
    }

    text {
        font-size: 16rpx;
        font-weight: 700;
        letter-spacing: 2rpx;
    }

    &:active {
        transform: translateY(2rpx);
    }
}

.empty-tip {
    padding: 40rpx;
    text-align: center;
    background: #f5f7ff;
    border-radius: 16rpx;

    text {
        font-size: 22rpx;
        color: #94a3b8;
    }
}

/* 报告: 答案/解析卡片 */
.ans-card {
    margin-top: 16rpx;
    padding: 16rpx;
    background: #f5f7ff;
    border-radius: 20rpx;

    &.ai {
        background: linear-gradient(135deg, #fef3c7, #fde68a);
    }

    &-title {
        display: flex;
        align-items: center;
        gap: 10rpx;
        margin-bottom: 12rpx;

        text {
            font-size: 24rpx;
            font-weight: 700;
            color: #312e81;
        }
    }

    &-bar {
        width: 6rpx;
        height: 22rpx;
        border-radius: 3rpx;
        background: linear-gradient(180deg, #818cf8, #4f46e5);

        &.ai {
            background: linear-gradient(180deg, #fbbf24, #d97706);
        }
    }

    &-body {
        font-size: 22rpx;
        color: #312e81;
        line-height: 1.7;
        padding: 0 4rpx;

        :deep(image) { max-width: 100%; height: auto; }
        :deep(.formula-text) {
            font-family: 'Times New Roman', serif;
            font-style: italic;
            color: #1e1b4b;
            font-size: 22rpx;
        }

        &.pic {
            display: flex;
            flex-direction: column;
            gap: 12rpx;

            image {
                max-width: 100%;
                border-radius: 12rpx;
            }
        }
    }
}
</style>
