<template>
    <view class="history-page">
        <!-- 顶部导航栏 -->
        <view class="nav-header">
            <view class="nav-back-btn" @tap="onBack">
                <text class="back-text">返回</text>
            </view>
            <text class="nav-title">患者历程</text>
            <view class="nav-placeholder"></view>
        </view>

        <!-- 患者信息卡片 -->
        <view class="info-card" v-if="patient">
            <view class="info-header">
                <view class="avatar-circle">
                    <text class="avatar-letter">{{ patient.avatar }}</text>
                </view>
                <view class="info-base">
                    <view class="info-name-row">
                        <text class="info-name">{{ patient.patName }}</text>
                        <text class="info-gender">{{ patient.gender }} · {{ patient.admAge }} · {{ patient.patExtNo }}</text>
                    </view>
                </view>
                <view class="collapse-btn" @tap="toggleExpand">
                    <text class="collapse-text">{{ expanded ? '收起' : '展开' }}</text>
                    <text class="collapse-arrow" :class="{ 'collapse-arrow-up': expanded }">▾</text>
                </view>
            </view>
            <view class="loading-mask" v-if="loading">
                <text class="loading-text">加载中...</text>
            </view>


            <view class="info-grid" v-if="expanded">
                <view class="info-item">
                    <text class="info-label">科室</text>
                    <text class="info-value">{{ patient.admLoc }}</text>
                </view>
                <view class="info-item">
                    <text class="info-label">接诊医生</text>
                    <text class="info-value">{{ patient.admDoc }}</text>
                </view>
                <view class="info-item">
                    <text class="info-label">初/复诊</text>
                    <text class="info-value">{{ patient.firstAdm }}</text>
                </view>
                <view class="info-item">
                    <text class="info-label">身份证号</text>
                    <text class="info-value">{{ patient.IDCardNo }}</text>
                </view>
                <view class="info-item">
                    <text class="info-label">手机号</text>
                    <text class="info-value">{{ patient.mobile }}</text>
                </view>
                <view class="info-item">
                    <text class="info-label">住址</text>
                    <text class="info-value">{{ patient.address }}</text>
                </view>
                <view class="info-item info-item-full">
                    <text class="info-label">挂号科室</text>
                    <text class="info-value">{{ patient.regLoc }}</text>
                </view>
            </view>
        </view>

        <!-- 标签栏 -->
        <view class="tabs">
            <view
                class="tab-item"
                :class="{ 'tab-active': currentTab === item.code }"
                v-for="(item, index) in tabs"
                :key="index"
                @tap="switchTab(item.code)"
            >
                <text class="tab-text" :class="{ 'tab-text-active': currentTab === item.code }">{{ item.label }}</text>
                <view v-if="currentTab === item.code" class="tab-underline"></view>
            </view>
        </view>

        <!-- 内容区 -->
        <scroll-view class="content-scroll" scroll-y>
            <!-- 历程时间线 -->
            <view class="timeline" v-if="currentTab === 'timeline'">
                <view class="timeline-item" v-for="(node, index) in timeline" :key="node.key || index">
                    <view class="timeline-dot"></view>
                    <view class="timeline-line" v-if="index !== timeline.length - 1"></view>
                    <view class="timeline-content" @tap="openPage(node)">
                        <view class="timeline-title-row">
                            <text :class="node.desc.indexOf('病历') > -1 ? 'timeline-title blue' : 'timeline-title'">{{ node.desc }}</text>
                            <text class="timeline-time">{{ node.datetime }}</text>
                        </view>
                        <view class="timeline-tags" v-if="node.oper && node.oper.indexOf('用户') < 0">
                            <text class="timeline-tag">{{ node.oper}}</text>
                        </view>
                    </view>
                </view>
                <view class="placeholder-box" v-if="!timeline.length">
                    <text class="placeholder-text">暂无历程记录</text>
                </view>
            </view>

            <!-- 聊天记录 -->
            <view class="chat-box" v-else-if="currentTab === 'chat'">
                <view class="doc-summary" v-if="summary">
                    <view class="doc-summary-row">
                        <text class="doc-summary-label">就诊日期</text>
                        <text class="doc-summary-value">{{ summary.admDate }} {{ summary.admTime }}</text>
                    </view>
                    <view class="doc-summary-row">
                        <text class="doc-summary-label">就诊类型</text>
                        <text class="doc-summary-value">{{ summary.admType }}</text>
                    </view>
                    <view class="doc-summary-row">
                        <text class="doc-summary-label">就诊状态</text>
                        <text class="doc-summary-value">{{ summary.queueStatus }}</text>
                    </view>
                    <view class="doc-summary-row">
                        <text class="doc-summary-label">过敏史</text>
                        <text class="doc-summary-value">{{ summary.AllergyFlag === 'Y' ? ('有 (' + (summary.AllergyDesc || '') + ')') : '无' }}</text>
                    </view>
                    <view class="doc-summary-row" v-if="summary.symptom">
                        <text class="doc-summary-label">主诉症状</text>
                        <text class="doc-summary-value">{{ summary.symptom }}</text>
                    </view>
                </view>
                <view
                    v-for="(msg, index) in messages"
                    :key="msg.msgID + '_' + index"
                >
                    <!-- 消息类型2: 撤回 -->
                    <view v-if="msg.msgType == '2'" class="message-withdrawn">
                        {{ msg.direction === 'left' ? '对方撤回了一条消息' : '你撤回了一条消息' }}
                    </view>

                    <!-- 消息类型3: 时间戳 -->
                    <view v-else-if="msg.msgType == '3'" class="message-timestamp">
                        {{ msg.sendTime }}
                    </view>

                    <!-- 消息类型1: 普通消息（文本/图片/视频/语音） -->
                    <view
                        v-else
                        class="chat-msg"
                        :class="msg.direction === 'right' ? 'chat-right' : 'chat-left'"
                    >
                        <view class="chat-bubble">
                            <!-- 文本消息 -->
                            <text class="chat-text" v-if="msg.mediaType === 'text'">{{ msg.consultText }}</text>

                            <!-- 图片消息 -->
                            <view
                                v-else-if="msg.picture || (msg.pictureLoading && msg.mediaType === 'image')"
                                class="bubble-image-wrap chat-image-wrap"
                                @tap.stop="viewOriginal"
                                :data-page="msg"
                            >
                                <image v-if="msg.picture" :src="msg.picture" mode="widthFix" class="bubble-image chat-image" />
                                <view v-else class="chat-loading">图片加载中...</view>
                            </view>

                            <!-- 视频消息 -->
                            <view
                                v-else-if="msg.video || (msg.pictureLoading && msg.mediaType === 'video')"
                                class="bubble-video chat-video"
                            >
                                <video
                                    v-if="msg.video"
                                    class="chat-video-el"
                                    :src="msg.video"
                                    controls
                                    object-fit="contain"
                                    :show-center-play-btn="true"
                                    play-btn-position="center"
                                ></video>
                                <view v-else class="chat-loading">视频上传中...</view>
                                <view v-if="msg.videoDuration && !msg.video" class="video-duration-badge">{{ formatVideoDuration(msg.videoDuration) }}</view>
                            </view>

                            <!-- 音频消息 -->
                            <view
                                v-else-if="msg.sound"
                                class="bubble-audio chat-audio"
                                @tap.stop="playAudio"
                                :data-page="msg"
                            >
                                <view
                                    class="audio-icon-wrap"
                                    :class="[msg.direction === 'right' ? 'icon-sent' : 'icon-received', playingAudioId === msg.msgID ? 'is-playing' : '']"
                                >
                                    <view class="audio-icon">
                                        <view class="audio-icon-waves">
                                            <view class="audio-icon-wave"></view>
                                            <view class="audio-icon-wave"></view>
                                            <view class="audio-icon-wave"></view>
                                        </view>
                                    </view>
                                </view>
                                <view class="audio-duration-text" v-if="msg.soundDuration">{{ formatAudioDuration(msg.soundDuration) }}"</view>
                            </view>
                        </view>
                        <text class="chat-time">{{ msg.sendTime }}</text>
                    </view>
                </view>
                <view class="placeholder-box" v-if="!messages.length">
                    <text class="placeholder-text">暂无聊天记录</text>
                </view>
            </view>

            <!-- 医疗文档 -->
            <view class="doc-box" v-else-if="currentTab === 'doc'">
                <view class="doc-diag" v-if="diag.length">
                    <text class="doc-section-title">诊断信息</text>
                    <view class="doc-diag-item" v-for="(item, index) in diag" :key="index">
                        <view class="doc-diag-head">
                            <view class="doc-diag-name-wrap">
                                <text class="doc-diag-name">{{ item.ICD10 }}</text>
                                <text class="doc-diag-main" v-if="item.MainFlag === 'Y'">主诊断</text>
                            </view>
                            <text class="doc-diag-code">{{ item.ICD10Code }}</text>
                        </view>
                        <text class="doc-diag-remark" v-if="item.Remarks">备注：{{ item.Remarks }}</text>
                    </view>
                </view>

                <view class="doc-order" v-if="otherOrder.length">
                    <text class="doc-section-title">检验检查</text>
                    <view class="doc-order-list">
                        <text class="doc-order-item" v-for="(item, index) in otherOrder" :key="index">
                            <text class="doc-order-index">{{ index + 1 }}.</text>
                            <text class="doc-order-name">{{ item.Descripts }}</text>
                        </text>
                    </view>
                </view>

                <view class="doc-drug" v-if="drugGroups.length">
                    <text class="doc-section-title">药品信息</text>
                    <view class="doc-drug-item" v-for="(group, gIndex) in drugGroups" :key="gIndex">
                        <view class="doc-drug-head">
                            <view class="doc-drug-name-list">
                                <text class="doc-drug-name-line" v-for="(item, iIndex) in group.list" :key="iIndex">
                                    {{ item.medItemName || item.Descripts }}<text v-if="item.qty || item.unit"> *{{ item.qty }}{{ item.unit }}</text>
                                </text>
                            </view>
                        </view>
                        <view class="doc-drug-detail">
                            <text class="doc-drug-cell" v-if="group.usag">用法：{{ group.usag }}</text>
                            <text class="doc-drug-cell" v-if="group.freq">频次：{{ group.freq }}</text>
                            <text class="doc-drug-cell" v-if="group.durQty">疗程：{{ group.durQty }}{{ group.durUnit }}</text>
                        </view>
                    </view>
                </view>

                <view class="placeholder-box" v-if="!summary && !diag.length && !drug.length && !otherOrder.length">
                    <text class="placeholder-text">暂无医疗文档</text>
                </view>
            </view>
        </scroll-view>

        <!-- 信息采集单（只读查看，复用 medicalRecord 的信息采集单模块） -->
        <view class="info-form-mask" v-if="infoFormVisible" @tap="closeInfoForm">
            <view class="info-form-panel" @tap.stop>
                <view class="info-form-header">
                    <text class="info-form-title">门诊病历</text>
                    <text class="info-form-close" @tap="closeInfoForm">关闭</text>
                </view>
                <scroll-view class="info-form-body" scroll-y>
                    <view class="ph-info-collection" v-if="formData.length > 0">
                        <view class="ph-info-item" v-for="(item, index) in formData" :key="index">
                            <view class="ph-info-label">{{ item.label }}</view>
                            <!-- 图片类型：只读展示 -->
                            <view v-if="item.type === 'casepluginimage'" class="ph-info-image-box">
                                <block v-if="getImageList(item.key).length > 0">
                                    <view class="ph-info-image-item" v-for="(imgUrl, imgIdx) in getImageList(item.key)" :key="imgIdx">
                                        <image
                                            class="ph-info-image"
                                            :src="urlImage(imgUrl)"
                                            mode="aspectFill"
                                            @error="onImageError(item.key, imgIdx)"
                                            @tap="previewImage(item.key, imgIdx)"
                                        />
                                    </view>
                                </block>
                                <view v-else class="ph-info-image-empty">暂无图片</view>
                            </view>
                            <!-- 下拉/单选等带选项类型：只读展示 label -->
                            <view
                                v-else-if="item.type === 'select' || item.type === 'radio' || item.type === 'checkbox'"
                                class="ph-info-value"
                                :class="{ 'ph-info-placeholder': !getDisplayValue(item) }"
                            >
                                {{ getDisplayValue(item) || '暂无' }}
                            </view>
                            <!-- 其他类型（input/date/textarea 等）：只读值 -->
                            <view v-else class="ph-info-value" :class="{ 'ph-info-placeholder': !getDisplayValue(item) }">
                                {{ getDisplayValue(item) || '暂无' }}
                            </view>
                        </view>
                    </view>
                    <view class="ph-placeholder-box" v-if="infoFormLoading">
                        <text class="ph-placeholder-text">加载中...</text>
                    </view>
                    <view class="ph-placeholder-box" v-if="!infoFormLoading && formData.length === 0">
                        <text class="ph-placeholder-text">暂无信息采集数据</text>
                    </view>
                </scroll-view>
            </view>
        </view>
    </view>
</template>

<script>
import { $http } from '../../../config/https.js';
import httpConfig from '../../../config/httpConfig.js';

export default {
    data() {
        return {
            expanded: false,
            loading: false,
            currentTab: 'timeline',
            tabs: [
                { code: 'timeline', label: '历程时间线' },
                { code: 'chat', label: '聊天记录' },
                { code: 'doc', label: '医疗文档' }
            ],
            patient: null,
            admID: '',
            // 历程时间线
            timeline: [],
            // 聊天记录
            messages: [],
            // 当前正在播放的语音 msgID
            playingAudioId: '',
            // 患者主诉/就诊概要
            summary: null,
            // 诊断信息
            diag: [],
            // 药品信息
            drug: [],
            // 其他医嘱
            otherOrder: [],
            // 信息采集单（只读查看）
            infoFormVisible: false,
            infoFormLoading: false,
            formData: [],
            dataKeyObj: {},
            formDataSource: {},
            imageLoadError: {},
            TempHtmlStr: ''
        };
    },
    onLoad(options) {
        // 从接诊中心携带参数
        this.admID = options.admID || '';
        this.loadPatientHistory();
    },
    computed: {
        // 药品按 用法/频次/疗程 分组，相同则合并显示
        drugGroups() {
            const map = {};
            this.drug.forEach((item) => {
                const key = [item.usag || '', item.freq || '', item.durQty || '', item.durUnit || ''].join('||');
                if (!map[key]) {
                    map[key] = {
                        usag: item.usag,
                        freq: item.freq,
                        durQty: item.durQty,
                        durUnit: item.durUnit,
                        list: []
                    };
                }
                map[key].list.push(item);
            });
            return Object.keys(map).map((k) => map[k]);
        }
    },
    methods: {
        onBack() {
            uni.navigateBack({
                delta: 1,
                fail: () => {
                    uni.switchTab({ url: '/pages/tabBar/home/home' });
                }
            });
        },
        toggleExpand() {
            this.expanded = !this.expanded;
        },
        switchTab(code) {
            this.currentTab = code;
        },
        // 判断普通消息（msgType==='1'）的媒体子类型：文本 / 图片 / 视频 / 语音
        // 注意：msgType 语义为 1-普通 2-撤回 3-时间戳，媒体类型由字段区分
        getMsgType(m) {
            if (!m) return 'text';
            // 优先按顶层字段判断
            if (m.picture || (m.msgData && (m.msgData.picture || (m.msgData.imgUrl)))) return 'image';
            if (m.video || (m.msgData && (m.msgData.video || (m.msgData.msg && m.msgData.msg.video)))) return 'video';
            if (m.sound || m.voice || (m.msgData && (m.msgData.sound || (m.msgData.msg && m.msgData.msg.voice)))) return 'voice';
            // 兜底：根据 msgData 结构判断
            const d = m.msgData;
            if (d) {
                if (m.video || (d.msg && d.msg.video) || d.video) return 'video';
                if (m.sound || (d.msg && d.msg.voice) || d.sound || m.voice) return 'voice';
                if (m.picture || d.picture || d.imgUrl || (d.msg && d.msg.imgUrl) || m.imgUrl) return 'image';
                if (d.text || d.content || m.consultText) return 'text';
            }
            return 'text';
        },
        // 拼接媒体完整地址（同 room.vue 逻辑）
        getMediaUrl(url) {
            if (!url) return '';
            if (url.indexOf('http://') === 0 || url.indexOf('https://') === 0) return url;
            return 'https://hlwyy.scsmysgkyy.cn' + url;
        },
        // 图片预览（点击查看大图，同会话图片可滑动）
        viewOriginal(e) {
            const item = e.currentTarget.dataset.page;
            if (!item || !item.picture) return;
            const urls = this.messages
                .filter((m) => m.mediaType === 'image' && m.picture)
                .map((m) => m.picture);
            uni.previewImage({
                current: item.picture,
                urls: urls.length ? urls : [item.picture]
            });
        },
        openPage(node) {
            if (node.desc && node.desc.indexOf('病历') > -1) {
                // 打开信息采集单（只读查看，不修改不保存）
                this.loadInfoForm(node.recordID);
            }
        },
        // 关闭信息采集单弹窗
        closeInfoForm() {
            this.infoFormVisible = false;
        },
        // 加载信息采集单：拉取模板 + 历史详情回显
        loadInfoForm(recordID) {
            if (!recordID) return;
            this.infoFormVisible = true;
            this.infoFormLoading = true;
            this.formData = [];
            this.dataKeyObj = {};
            this.formDataSource = {};
            this.imageLoadError = {};
            // 1. 获取模板信息（含 templateHtmlUrl，用于确认模板存在）
            $http.post('', this, {
                code: '06010115',
                data: { params: [{ admID: this.admID }] },
                success: (res) => {
                    let result = res.result || {};
                    this.TempHtmlStr = result.templateHtmlUrl || '';
                    if (!this.TempHtmlStr) {
                        this.infoFormLoading = false;
                        uni.showToast({ title: '未获取到信息采集单模板', icon: 'none' });
                    }
                }
            });
            // 2. 拉取历史病历详情（用于回显）
            $http.post('', this, {
                code: '06010117',
                data: {
                    emrCode: '18060011',
                    params: [{
                        recordID: recordID
                    }]
                },
                success: (res) => {
                    let result = res.result || res.data || {};
                    let list = result.data || result.recordDetail || [];
                    // 构建 formData（标签/类型/key）与 formDataSource（值）
                    let formList = [];
                    let sourceMap = {};
                    (list || []).forEach((item) => {
                        let key = item.uniqueCode || item.metaDataCode || '';
                        let type = item.filedType || 'input';
                        if (type === 'image') type = 'casepluginimage';
                        if (!key) return;
                        formList.push({ key: key, label: item.uniqueName || item.metaDataDesc || key, type: type });
                        sourceMap[key] = item.filedText !== undefined ? item.filedText : '';
                    });
                    this.formData = formList;
                    this.formDataSource = sourceMap;
                    this.infoFormLoading = false;
                },
                fail: () => {
                    this.infoFormLoading = false;
                }
            });
        },
        // 拼接图片地址
        urlImage(val) {
            if (!val) return '';
            if (val.indexOf('http') === 0 || val.indexOf('//') === 0) return val;
            let base = httpConfig.urlAddress || '';
            return base + (val.indexOf('/') === 0 ? val : '/' + val);
        },
        // 获取某字段的图片地址数组
        getImageList(key) {
            let val = this.formDataSource[key];
            if (!val) return [];
            let arr = [];
            if (typeof val === 'string') {
                arr = val.split(',').filter((s) => s && s.trim());
            } else if (Array.isArray(val)) {
                arr = val;
            } else {
                arr = [val];
            }
            let errs = this.imageLoadError[key] || [];
            return arr.map((s, idx) => (errs.indexOf(idx) > -1 ? '' : s)).filter(Boolean);
        },
        onImageError(key, idx) {
            if (!this.imageLoadError[key]) {
                this.$set(this.imageLoadError, key, []);
            }
            this.imageLoadError[key].push(idx);
        },
        previewImage(key, idx) {
            const urls = this.getImageList(key);
            if (!urls.length) return;
            uni.previewImage({ current: urls[idx], urls: urls });
        },
        // 计算只读展示值
        getDisplayValue(item) {
            if (!item) return '';
            let val = this.formDataSource[item.key];
            if (val === undefined || val === null || val === '') return '';
            if (item.type === 'casepluginimage') {
                return this.getImageList(item.key).length > 0 ? '图片' : '';
            }
            // 接口已返回中文文本（filedText），直接展示
            return val;
        },
        // 语音播放
        playAudio(e) {
            const item = e.currentTarget.dataset.page;
            if (!item || !item.sound) return;
            if (this.playingAudioId && this.playingAudioId !== item.msgID) {
                if (this.innerAudio) {
                    this.innerAudio.stop();
                    this.innerAudio.destroy();
                    this.innerAudio = null;
                }
            }
            if (this.playingAudioId === item.msgID) {
                // 再次点击停止
                this.playingAudioId = '';
                if (this.innerAudio) {
                    this.innerAudio.stop();
                    this.innerAudio.destroy();
                    this.innerAudio = null;
                }
                return;
            }
            this.playingAudioId = item.msgID;
            const innerAudio = uni.createInnerAudioContext();
            this.innerAudio = innerAudio;
            innerAudio.src = item.sound;
            innerAudio.play();
            innerAudio.onEnded(() => {
                this.playingAudioId = '';
                innerAudio.destroy();
                this.innerAudio = null;
            });
            innerAudio.onError(() => {
                this.playingAudioId = '';
                innerAudio.destroy();
                this.innerAudio = null;
            });
        },
        // 视频时长格式化（秒 -> mm:ss 或 ss″）
        formatVideoDuration(sec) {
            sec = Number(sec) || 0;
            const m = Math.floor(sec / 60);
            const s = sec % 60;
            return m > 0 ? (m + ':' + (s < 10 ? '0' : '') + s) : (s + '″');
        },
        // 语音时长格式化（秒 -> "s″"）
        formatAudioDuration(sec) {
            sec = Number(sec) || 0;
            return sec + '″';
        },
        loadPatientHistory() {
            const that = this;
            if (that.loading) return;
            that.loading = true;
            const data = {
                params: [{ admID: that.admID }]
            };
            $http.post('urlDeault', this, {
                code: '12100048',
                data: data,
                success: function (res) {
                    that.loading = false;
                    if (res.errorCode != '0') {
                        return;
                    }
                    const result = res.result || {};
                    const info = result.info || {};
                    const messageResult = result.messageResult || {};

                    // 用接口返回覆盖患者信息（字段按 12100048 实际返回映射）
                    that.patient = Object.assign({}, that.patient, {
                        ...info,
                        patName: info.patName || that.patient.patName,
                        gender: info.gender || that.patient.gender,
                        admAge: info.admAge || that.patient.admAge,
                        patType: info.patType || that.patient.patType,
                        admLoc: info.admLoc || that.patient.admLoc,
                        admDoc: info.admDoc || that.patient.admDoc,
                        firstAdm: info.firstAdm || that.patient.firstAdm,
                        IDCardNo: info.IDCardNo || that.patient.IDCardNo,
                        mobile: info.mobile || that.patient.mobile,
                        address: info.address || that.patient.address,
                        regLoc: info.regLoc || that.patient.regLoc
                    });
                    that.patient.avatar = (that.patient.patName || '?').substring(0, 1);

                    // 历程时间线（result.data）
                    if (Array.isArray(result.data)) {
                        that.timeline = result.data.map((n) => ({
                            key: n.index,
                            recordID: n.key,
                            desc: n.desc || '',
                            datetime: n.datetime || '',
                            oper: n.oper || ''
                        }));
                    }

                    // 聊天记录：兼容多种可能的接口返回字段名
                    const rawMsgs = messageResult.msgData ||
                        result.msgData ||
                        messageResult.list ||
                        result.list ||
                        [];
                    const msgs = [];
                    if (!Array.isArray(rawMsgs)) {
                        // 单条消息容错
                        rawMsgs && msgs.push(rawMsgs);
                    } else {
                        rawMsgs.forEach((m) => {
                            const msgType = String(m.msgType || '1');

                            // 消息类型2: 撤回 / 类型3: 时间戳，直接入列
                            if (msgType === '2' || msgType === '3') {
                                msgs.push({
                                    msgID: m.msgID,
                                    msgType: msgType,
                                    sendTime: m.sendTime || '',
                                    direction: m.direction || 'left',
                                    reEditFlag: m.reEditFlag || ''
                                });
                                return;
                            }

                            // 消息类型1: 普通消息（文本 / 图片 / 视频 / 语音）
                            const rawType = that.getMsgType(m);
                            if (!['text', 'image', 'video', 'voice'].includes(rawType)) return;

                            const base = {
                                msgID: m.msgID,
                                msgType: '1',
                                sendTime: m.sendTime || '',
                                direction: m.direction || 'left',
                                mediaType: rawType,
                                pictureLoading: false
                            };

                            if (rawType === 'text') {
                                base.consultText = m.consultText || '';
                            } else if (rawType === 'image') {
                                base.consultText =
                                    m.consultText ||
                                    (m.msgData && m.msgData.text) ||
                                    '';
                                base.picture = that.getMediaUrl(
                                    m.picture || (m.msgData && m.msgData.picture) || m.imgUrl || (m.msgData && m.msgData.imgUrl)
                                );
                            } else if (rawType === 'video') {
                                base.consultText =
                                    m.consultText ||
                                    (m.msgData && m.msgData.text) ||
                                    '';
                                const v = m.msgData && m.msgData.msg;
                                base.video = that.getMediaUrl(
                                    m.video || (v && v.video)
                                );
                                base.videoDuration = (v && v.videoTime) || m.videoDuration || 0;
                            } else if (rawType === 'voice') {
                                base.consultText = '';
                                const v = m.msgData && m.msgData.msg;
                                base.sound = that.getMediaUrl(
                                    m.sound || (v && v.voice) || m.voice
                                );
                                base.soundDuration = (v && v.voiceTime) || m.voiceTime || m.soundDuration || 0;
                            }

                            msgs.push(base);
                        });
                    }
                    that.messages = msgs;

                    // 患者主诉/就诊概要（result.messageSummary）
                    that.summary = result.messageSummary || null;

                    // 诊断信息（result.diag）
                    that.diag = Array.isArray(result.diag) ? result.diag : [];

                    // 药品信息（result.drug）
                    that.drug = Array.isArray(result.drug) ? result.drug : [];

                    // 其他医嘱（result.otherOrder）
                    that.otherOrder = Array.isArray(result.otherOrder) ? result.otherOrder : [];
                },
                fail: function () {
                    that.loading = false;
                }
            });
        }
    }
};
</script>

<style scoped>
.history-page {
    min-height: 100vh;
    background-color: #f5f6f8;
    display: flex;
    flex-direction: column;
}

/* 导航栏 */
.nav-header {
    height: 88rpx;
    background: linear-gradient(135deg, #4a9fff 0%, #2B84FF 100%);
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 0 24rpx;
    padding-top: var(--status-bar-height, 44rpx);
}

.nav-back-btn {
    padding: 8rpx 16rpx;
    border-radius: 24rpx;
}

.back-text {
    font-size: 26rpx;
    color: #ffffff;
}

.nav-title {
    font-size: 34rpx;
    font-weight: 600;
    color: #ffffff;
}

.nav-placeholder {
    width: 80rpx;
}

/* 患者信息卡片 */
.info-card {
    background: #ffffff;
    margin: 20rpx 24rpx 0;
    border-radius: 16rpx;
    padding: 24rpx;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
}

.info-header {
    display: flex;
    flex-direction: row;
    align-items: center;
}

.avatar-circle {
    width: 72rpx;
    height: 72rpx;
    border-radius: 50%;
    background: linear-gradient(135deg, #6bb3ff 0%, #4a9fff 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 18rpx;
}

.avatar-letter {
    font-size: 28rpx;
    font-weight: 600;
    color: #ffffff;
}

.info-base {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.info-name-row {
    display: flex;
    flex-direction: row;
    align-items: baseline;
}

.info-name {
    font-size: 32rpx;
    font-weight: 600;
    color: #1f2329;
    margin-right: 16rpx;
}

.info-gender {
    font-size: 24rpx;
    color: #8b98a8;
}

.info-sub {
    font-size: 24rpx;
    color: #8b98a8;
    margin-top: 6rpx;
}

.collapse-btn {
    display: flex;
    flex-direction: row;
    align-items: center;
}

.collapse-text {
    font-size: 24rpx;
    color: #2B84FF;
}

.collapse-arrow {
    font-size: 22rpx;
    color: #2B84FF;
    margin-left: 4rpx;
    transition: transform 0.2s;
}

.collapse-arrow-up {
    transform: rotate(180deg);
}

.info-grid {
    margin-top: 20rpx;
    padding-top: 20rpx;
    border-top: 1rpx solid #f0f2f5;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

.loading-mask {
    margin-top: 20rpx;
    padding-top: 20rpx;
    border-top: 1rpx solid #f0f2f5;
    text-align: center;
}

.loading-text {
    font-size: 24rpx;
    color: #8b98a8;
}

.info-item {
    width: 50%;
    display: flex;
    flex-direction: column;
    margin-bottom: 18rpx;
}

.info-item-full {
    width: 100%;
}

.info-label {
    font-size: 22rpx;
    color: #8b98a8;
    margin-bottom: 6rpx;
}

.info-value {
    font-size: 26rpx;
    color: #1f2329;
}

/* 标签栏 */
.tabs {
    background: #ffffff;
    display: flex;
    flex-direction: row;
    margin: 20rpx 24rpx 0;
    border-radius: 16rpx 16rpx 0 0;
    overflow: hidden;
}

.tab-item {
    flex: 1;
    padding: 26rpx 0;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.tab-text {
    font-size: 28rpx;
    color: #666666;
}

.tab-text-active {
    color: #2B84FF;
    font-weight: 600;
}

.tab-underline {
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 56rpx;
    height: 5rpx;
    background: #2B84FF;
    border-radius: 3rpx;
}

/* 内容区 */
.content-scroll {
    flex: 1;
    background: #ffffff;
    margin: 0 24rpx 24rpx;
    border-radius: 0 0 16rpx 16rpx;
    padding: 30rpx 24rpx;
    box-sizing: border-box;
    height: calc(100vh - 600rpx);
    width: initial!important;
}

/* 时间线 */
.timeline {
    display: flex;
    flex-direction: column;
}

.timeline-item {
    position: relative;
    padding-left: 40rpx;
}

.timeline-dot {
    position: absolute;
    left: 6rpx;
    top: 8rpx;
    width: 18rpx;
    height: 18rpx;
    border-radius: 50%;
    background: #2B84FF;
    z-index: 2;
}

.timeline-line {
    position: absolute;
    left: 14rpx;
    top: 24rpx;
    bottom: -20rpx;
    width: 2rpx;
    background: #e3e8ef;
}

.timeline-content {
    padding-bottom: 36rpx;
}

.timeline-title-row {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
}

.timeline-title {
    font-size: 30rpx;
    font-weight: 600;
    color: #1f2329;
}
.timeline-title.blue{
    color: #2B84FF;
    font-weight: 700;
}

.timeline-time {
    font-size: 24rpx;
    color: #8b98a8;
}

.timeline-desc {
    font-size: 26rpx;
    color: #4a5160;
    line-height: 40rpx;
    margin-top: 8rpx;
}

.timeline-tags {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 12rpx;
    margin-top: 12rpx;
}

.timeline-tag {
    padding: 4rpx 16rpx;
    background: #eaf4ff;
    color: #2B84FF;
    border-radius: 20rpx;
    font-size: 22rpx;
}

/* 占位 */
.placeholder-box {
    padding-top: 120rpx;
    display: flex;
    justify-content: center;
}

.placeholder-text {
    font-size: 28rpx;
    color: #b0b8c4;
}

/* 聊天记录 */
.chat-box {
    display: flex;
    flex-direction: column;
}

.chat-msg {
    display: flex;
    flex-direction: column;
    margin-bottom: 28rpx;
}

.chat-left {
    align-items: flex-start;
}

.chat-right {
    align-items: flex-end;
}

.chat-bubble {
    max-width: 78%;
    padding: 18rpx 24rpx;
    border-radius: 16rpx;
    font-size: 28rpx;
    line-height: 42rpx;
}

.chat-left .chat-bubble {
    background: #f0f2f5;
    color: #1f2329;
    border-top-left-radius: 4rpx;
}

.chat-right .chat-bubble {
    background: #2B84FF;
    color: #ffffff;
    border-top-right-radius: 4rpx;
}

.chat-text {
    word-break: break-all;
}

/* 撤回提示 */
.message-withdrawn {
    text-align: center;
    font-size: 24rpx;
    color: #b0b8c4;
    margin: 16rpx 0;
}

.re-edit-link {
    color: #2B84FF;
    margin-left: 8rpx;
}

/* 时间戳 */
.message-timestamp {
    text-align: center;
    font-size: 22rpx;
    color: #b0b8c4;
    margin: 16rpx 0;
}

/* 图片消息 */
.bubble-image-wrap {
    position: relative;
}

.chat-image {
    width: 320rpx;
    max-height: 420rpx;
    border-radius: 12rpx;
    background: #f0f2f5;
}

/* 视频消息 */
.bubble-video {
    position: relative;
    width: 320rpx;
    border-radius: 12rpx;
    overflow: hidden;
    background: #000000;
}

.chat-video-el {
    width: 320rpx;
    height: 420rpx;
    display: block;
    border-radius: 12rpx;
}

/* 视频播放按钮遮罩 */
.video-play-btn-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
}

.play-icon-circle {
    width: 72rpx;
    height: 72rpx;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    position: relative;
}

.play-icon-circle::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 54%;
    transform: translate(-50%, -50%);
    border-style: solid;
    border-width: 16rpx 0 16rpx 26rpx;
    border-color: transparent transparent transparent #ffffff;
}

/* 视频时长角标 */
.video-duration-badge {
    position: absolute;
    right: 10rpx;
    bottom: 10rpx;
    background: rgba(0, 0, 0, 0.6);
    color: #ffffff;
    font-size: 22rpx;
    padding: 2rpx 12rpx;
    border-radius: 20rpx;
    z-index: 3;
}

/* 加载中 */
.chat-loading {
    font-size: 24rpx;
    color: #b0b8c4;
    padding: 40rpx 20rpx;
    text-align: center;
}

/* 语音消息 */
.bubble-audio {
    display: flex;
    flex-direction: row;
    align-items: center;
    min-width: 150rpx;
}

.chat-right .bubble-audio {
    flex-direction: row-reverse;
}

.audio-icon-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
}

.audio-icon {
    display: flex;
    flex-direction: row;
    align-items: center;
}

.audio-icon-waves {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    height: 34rpx;
}

.audio-icon-wave {
    width: 6rpx;
    background: #1f2329;
    border-radius: 3rpx;
    margin-right: 5rpx;
}

.chat-right .audio-icon-wave {
    background: #ffffff;
}

.audio-icon-wave:nth-child(1) {
    height: 14rpx;
}

.audio-icon-wave:nth-child(2) {
    height: 30rpx;
}

.audio-icon-wave:nth-child(3) {
    height: 22rpx;
}

.audio-icon-wrap.is-playing .audio-icon-wave {
    animation: audio-wave 0.9s infinite ease-in-out;
}

.audio-icon-wrap.is-playing .audio-icon-wave:nth-child(2) {
    animation-delay: 0.2s;
}

.audio-icon-wrap.is-playing .audio-icon-wave:nth-child(3) {
    animation-delay: 0.4s;
}

@keyframes audio-wave {
    0%, 100% {
        transform: scaleY(0.45);
    }
    50% {
        transform: scaleY(1);
    }
}

.audio-duration-text {
    font-size: 26rpx;
    color: #1f2329;
    margin-left: 14rpx;
}

.chat-right .audio-duration-text {
    color: #ffffff;
    margin-left: 0;
    margin-right: 14rpx;
}

.chat-time {
    font-size: 20rpx;
    color: #b0b8c4;
    margin-top: 8rpx;
}

/* 医疗文档 */
.doc-box {
    display: flex;
    flex-direction: column;
}

.doc-summary {
    background: #f7f9fc;
    border-radius: 12rpx;
    padding: 24rpx;
    margin-bottom: 24rpx;
}

.doc-summary-row {
    display: flex;
    flex-direction: row;
    margin-bottom: 14rpx;
}

.doc-summary-row:last-child {
    margin-bottom: 0;
}

.doc-summary-label {
    width: 160rpx;
    font-size: 26rpx;
    color: #8b98a8;
    flex-shrink: 0;
}

.doc-summary-value {
    flex: 1;
    font-size: 26rpx;
    color: #1f2329;
    line-height: 40rpx;
}

.doc-section-title {
    font-size: 28rpx;
    font-weight: 600;
    color: #1f2329;
    margin-bottom: 16rpx;
}

.doc-diag-item {
    border: 1rpx solid #eef1f5;
    border-radius: 12rpx;
    padding: 20rpx;
    margin-bottom: 16rpx;
}

.doc-diag-head {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
}

.doc-diag-name {
    font-size: 28rpx;
    font-weight: 600;
    color: #1f2329;
}

.doc-diag-code {
    font-size: 22rpx;
    color: #8b98a8;
}

.doc-diag-remark {
    font-size: 24rpx;
    color: #4a5160;
    margin-top: 8rpx;
}

.doc-diag-name-wrap {
    display: flex;
    flex-direction: row;
    align-items: baseline;
}

.doc-diag-main {
    font-size: 20rpx;
    color: #ffffff;
    background: #ff7a45;
    border-radius: 16rpx;
    padding: 2rpx 12rpx;
    margin-left: 12rpx;
}

/* 其他医嘱 */
.doc-order {
    margin-top: 32rpx;
}

.doc-order-list {
    display: flex;
    flex-direction: column;
}

.doc-order-item {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    font-size: 26rpx;
    color: #1f2329;
    line-height: 44rpx;
}

.doc-order-index {
    color: #8b98a8;
    margin-right: 8rpx;
}

.doc-order-name {
    flex: 1;
}

/* 药品信息 */
.doc-drug {
    margin-top: 32rpx;
}

.doc-drug-item {
    border: 1rpx solid #eef1f5;
    border-radius: 12rpx;
    padding: 20rpx;
    margin-bottom: 16rpx;
}

.doc-drug-head {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
}

.doc-drug-name-list {
    display: flex;
    flex-direction: column;
}

.doc-drug-name-line {
    font-size: 28rpx;
    font-weight: 600;
    color: #1f2329;
    line-height: 46rpx;
}

.doc-drug-spec {
    font-size: 22rpx;
    color: #8b98a8;
}

.doc-drug-detail {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 12rpx 32rpx;
    margin-top: 12rpx;
}

.doc-drug-cell {
    font-size: 24rpx;
    color: #4a5160;
}

/* 信息采集单弹窗（只读查看） */
.info-form-mask {
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: center;
}
.info-form-panel {
    width: 86%;
    max-height: 80vh;
    background: #ffffff;
    border-radius: 20rpx;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.info-form-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 28rpx 32rpx;
    border-bottom: 1rpx solid #eef0f4;
}
.info-form-title {
    font-size: 32rpx;
    font-weight: 600;
    color: #222;
}
.info-form-close {
    font-size: 28rpx;
    color: #4f7cff;
}
.info-form-body {
    padding: 24rpx 32rpx 40rpx;
    max-height: 64vh;
}
.ph-info-collection {
    display: flex;
    flex-direction: column;
}
.ph-info-item {
    display: flex;
    flex-direction: row;
    padding: 20rpx 0;
    border-bottom: 1rpx solid #f2f3f6;
}
.ph-info-label {
    width: 220rpx;
    flex-shrink: 0;
    font-size: 28rpx;
    color: #8a909c;
}
.ph-info-value {
    flex: 1;
    font-size: 28rpx;
    color: #222;
    word-break: break-all;
}
.ph-info-placeholder {
    color: #b6bac2;
}
.ph-info-image-box {
    flex: 1;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 16rpx;
}
.ph-info-image-item {
    width: 160rpx;
    height: 160rpx;
    border-radius: 12rpx;
    overflow: hidden;
    background: #f2f3f6;
}
.ph-info-image {
    width: 160rpx;
    height: 160rpx;
}
.ph-info-image-empty {
    font-size: 28rpx;
    color: #b6bac2;
}
.ph-placeholder-box {
    padding: 80rpx 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ph-placeholder-text {
    font-size: 28rpx;
    color: #b6bac2;
}
</style>
