<template>
    <div class="apt-h5">
        <template v-if="currentView === 'list'">
            <header class="apt-h5-topbar">
                <div class="apt-h5-search">
                    <el-input
                        v-model="formData.patient_name"
                        placeholder="患者姓名"
                        clearable
                        :prefix-icon="Search"
                        @keyup.enter="handleSearch"
                        @clear="handleSearch"
                    />
                    <el-button class="apt-h5-search-btn" type="primary" @click="handleSearch">查询</el-button>
                </div>

                <div class="apt-h5-status apt-h5-scroll">
                    <span
                        v-for="tab in statusTabs"
                        :key="tab.value"
                        :class="['apt-h5-chip', { active: activeTab === tab.value }]"
                        @click="handleTabChange(tab.value)"
                    >
                        {{ tab.label }}
                        <em v-if="tab.count">{{ tab.count }}</em>
                    </span>
                </div>

                <div class="apt-h5-date apt-h5-scroll">
                    <span
                        v-for="item in dateTabs"
                        :key="item.value || 'all'"
                        :class="['apt-h5-pill', { active: formData.date_preset === item.value }]"
                        @click="handleDatePresetChange(item.value)"
                    >
                        {{ item.label }}
                    </span>
                </div>

                <div class="apt-h5-quick">
                    <div class="apt-h5-quick-group">
                        <span class="apt-h5-quick-label">确认</span>
                        <span
                            v-for="item in confirmedOptions"
                            :key="item.value || 'all'"
                            :class="['apt-h5-pill', { active: formData.diagnosis_confirmed === item.value }]"
                            @click="handleConfirmedChange(item.value)"
                        >
                            {{ item.label }}
                        </span>
                    </div>
                    <el-button link type="primary" size="small" class="apt-h5-more-toggle" @click="showMoreFilter = !showMoreFilter">
                        {{ showMoreFilter ? '收起' : '更多' }}
                        <el-icon :class="{ 'rotate-180': showMoreFilter }"><ArrowDown /></el-icon>
                    </el-button>
                </div>

                <div v-show="showMoreFilter" class="apt-h5-more-filter">
                    <el-input
                        v-if="isAdmin"
                        v-model="formData.doctor_name"
                        placeholder="医生"
                        clearable
                        size="small"
                        @keyup.enter="handleSearch"
                        @clear="handleSearch"
                    />
                    <el-date-picker
                        v-model="customDateRange"
                        type="daterange"
                        range-separator="至"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        value-format="YYYY-MM-DD"
                        size="small"
                        class="apt-h5-date-range"
                        @change="applyCustomDate"
                    />
                    <el-button size="small" @click="handleReset">重置</el-button>
                </div>
            </header>

            <main class="apt-h5-list" v-loading="pager.loading">
                <div v-if="pager.lists.length === 0 && !pager.loading" class="apt-h5-empty">
                    <el-empty description="暂无问诊" :image-size="120" />
                </div>

                <article v-for="row in pager.lists" :key="row.id" :class="['apt-h5-card', cardClass(row)]">
                    <header class="apt-h5-card-head" @click="handleDetail(row)">
                        <div class="apt-h5-avatar">{{ (row.patient_name || '患').charAt(0) }}</div>
                        <div class="apt-h5-title">
                            <div class="apt-h5-name">
                                {{ row.patient_name || '-' }}
                                <span v-if="row.gender === 1 || row.gender === 0" class="apt-h5-meta">{{ row.gender === 1 ? '男' : '女' }}</span>
                                <span v-if="row.age != null" class="apt-h5-meta">{{ row.age }}岁</span>
                            </div>
                            <div class="apt-h5-sub">#{{ row.id }} · {{ maskPhone(row.patient_phone) || '-' }}</div>
                        </div>
                        <div class="apt-h5-tags">
                            <span :class="['apt-h5-tag', statusTagClass(row.status)]">{{ row.status_desc || statusLabel(row.status) }}</span>
                            <span v-if="row.diagnosis_confirmed" class="apt-h5-tag apt-h5-tag--ok">已确认</span>
                            <span v-else class="apt-h5-tag apt-h5-tag--warn">未确认</span>
                        </div>
                    </header>

                    <section class="apt-h5-card-body" @click="handleDetail(row)">
                        <div class="apt-h5-row">
                            <span class="apt-h5-row-key">预约</span>
                            <span class="apt-h5-row-val">{{ row.appointment_date || '-' }} {{ row.appointment_time || '' }}</span>
                        </div>
                        <div class="apt-h5-row">
                            <span class="apt-h5-row-key">医生</span>
                            <span class="apt-h5-row-val">{{ row.doctor_name || '-' }}</span>
                        </div>
                        <div class="apt-h5-row">
                            <span class="apt-h5-row-key">助理</span>
                            <span class="apt-h5-row-val">{{ row.assistant_name || '-' }}</span>
                        </div>
                        <div class="apt-h5-row">
                            <span class="apt-h5-row-key">开方</span>
                            <span class="apt-h5-row-val">
                                <span v-if="row.has_prescription" class="apt-h5-inline-tag apt-h5-inline-tag--ok">已开方</span>
                                <span v-else class="apt-h5-inline-tag">未开方</span>
                                <span v-if="row.has_prescription && row.prescription_is_system_auto === 1" class="apt-h5-inline-tag apt-h5-inline-tag--warn">系统代开</span>
                            </span>
                        </div>
                        <div v-if="row.remark" class="apt-h5-row apt-h5-row--remark">
                            <span class="apt-h5-row-key">备注</span>
                            <span class="apt-h5-row-val">{{ row.remark }}</span>
                        </div>
                    </section>

                    <footer class="apt-h5-card-foot">
                        <el-button
                            v-if="hasPermission(['tcm.diagnosis/edit'])"
                            type="primary"
                            size="small"
                            plain
                            @click="handleEdit(row)"
                        >
                            编辑患者
                        </el-button>
                        <el-button
                            v-if="row.status !== 3 && hasPermission(['doctor.appointment/prescription'])"
                            type="primary"
                            size="small"
                            :icon="Phone"
                            @click="handleChat(row)"
                        >
                            通话
                        </el-button>
                        <el-button
                            v-if="hasPermission(['tcm.diagnosis/kaifang'])"
                            :type="prescriptionActionLabel(row) === '查看' ? 'success' : 'primary'"
                            size="small"
                            plain
                            @click="handlePrescription(row)"
                        >
                            {{ prescriptionActionLabel(row) }}
                        </el-button>
                        <el-button size="small" class="apt-h5-more-btn" @click="openMoreSheet(row)">
                            更多<el-icon class="el-icon--right"><ArrowDown /></el-icon>
                        </el-button>
                    </footer>
                </article>

                <div v-if="hasMore" class="apt-h5-load-more" @click="loadMore">
                    {{ pager.loading ? '加载中...' : '加载更多' }}
                </div>
                <div v-if="!hasMore && pager.lists.length > 0" class="apt-h5-no-more">没有更多了</div>
            </main>

            <el-drawer
                v-model="moreSheetVisible"
                :title="moreSheetRow ? `${moreSheetRow.patient_name || '问诊'} · 更多操作` : '更多操作'"
                direction="btt"
                size="auto"
                :destroy-on-close="true"
            >
                <div v-if="moreSheetRow" class="apt-h5-actions">
                    <button
                        v-if="moreSheetRow.status !== 3 && hasPermission(['tcm.diagnosis/videoQr'])"
                        class="apt-h5-action"
                        @click="runAction('videoQr')"
                    >
                        <el-icon><Picture /></el-icon>
                        <span>视频二维码</span>
                    </button>
                    <button
                        v-if="moreSheetRow.status !== 3 && hasPermission(['doctor.appointment/complete'])"
                        class="apt-h5-action"
                        @click="runAction('complete')"
                    >
                        <el-icon><CircleCheck /></el-icon>
                        <span>完成</span>
                    </button>
                    <button
                        v-if="hasPermission(['tcm.diagnosis/kaifang'])"
                        class="apt-h5-action"
                        @click="runAction('case')"
                    >
                        <el-icon><Document /></el-icon>
                        <span>病历</span>
                    </button>
                    <button
                        v-if="moreSheetRow.status === 1 && hasPermission(['doctor.appointment/cancel'])"
                        class="apt-h5-action apt-h5-action--danger"
                        @click="runAction('cancel')"
                    >
                        <el-icon><CircleClose /></el-icon>
                        <span>取消挂号</span>
                    </button>
                </div>
            </el-drawer>
        </template>

        <template v-else>
            <header class="apt-h5-detail-topbar">
                <button class="apt-h5-back" @click="backToList">
                    <span>‹</span>
                    返回
                </button>
                <div class="apt-h5-detail-title">
                    <strong>{{ detailData?.patient_name || detailSourceRow?.patient_name || '问诊详情' }}</strong>
                    <small>{{ detailData?.appointment_date || detailSourceRow?.appointment_date || '' }} {{ detailData?.appointment_time || detailSourceRow?.appointment_time || '' }}</small>
                </div>
            </header>

            <main v-loading="detailLoading" class="apt-h5-detail-page">
                <template v-if="detailData">
                    <section class="apt-h5-detail-section">
                        <h3>预约信息</h3>
                        <div class="apt-h5-detail-grid">
                            <div><span>挂号ID</span><strong>{{ detailData.id || '-' }}</strong></div>
                            <div><span>状态</span><strong>{{ detailData.status_desc || statusLabel(detailData.status) }}</strong></div>
                            <div><span>医生</span><strong>{{ detailData.doctor_name || '-' }}</strong></div>
                            <div><span>预约时间</span><strong>{{ detailData.appointment_date || '-' }} {{ detailData.appointment_time || '' }}</strong></div>
                            <div><span>时段</span><strong>{{ detailData.period === 'morning' ? '上午' : detailData.period === 'afternoon' ? '下午' : '-' }}</strong></div>
                            <div><span>预约类型</span><strong>{{ detailData.appointment_type_desc || '-' }}</strong></div>
                        </div>
                    </section>

                    <section class="apt-h5-detail-section">
                        <h3>患者信息</h3>
                        <div class="apt-h5-detail-grid">
                            <div><span>姓名</span><strong>{{ detailData.patient_name || '-' }}</strong></div>
                            <div><span>手机号</span><strong>{{ detailData.phone || detailData.patient_phone || '-' }}</strong></div>
                            <div class="apt-h5-detail-full"><span>身份证号</span><strong>{{ detailData.id_card || '-' }}</strong></div>
                            <div><span>性别</span><strong>{{ detailData.gender === 1 ? '男' : detailData.gender === 0 ? '女' : '-' }}</strong></div>
                            <div><span>年龄</span><strong>{{ detailData.age != null ? `${detailData.age}岁` : '-' }}</strong></div>
                            <div><span>诊断日期</span><strong>{{ detailData.diagnosis_date || '-' }}</strong></div>
                            <div><span>婚姻状态</span><strong>{{ maritalStatusLabel(detailData.marital_status) }}</strong></div>
                            <div><span>身高(cm)</span><strong>{{ detailData.height ?? '-' }}</strong></div>
                            <div><span>体重(kg)</span><strong>{{ detailData.weight ?? '-' }}</strong></div>
                            <div class="apt-h5-detail-full"><span>地区</span><strong>{{ detailData.region || '-' }}</strong></div>
                            <div><span>收缩压(mmHg)</span><strong>{{ detailData.systolic_pressure ?? '-' }}</strong></div>
                            <div><span>舒张压(mmHg)</span><strong>{{ detailData.diastolic_pressure ?? '-' }}</strong></div>
                            <div><span>空腹血糖(mmol/L)</span><strong>{{ detailData.fasting_blood_sugar ?? '-' }}</strong></div>
                            <div><span>诊断类型</span><strong>{{ getDictLabel(diagnosisTypeOptions, detailData.diagnosis_type) }}</strong></div>
                            <div><span>证型</span><strong>{{ getDictLabel(syndromeTypeOptions, detailData.syndrome_type) }}</strong></div>
                            <div><span>糖尿病期数</span><strong>{{ getDictLabel(diabetesTypeOptions, detailData.diabetes_type) }}</strong></div>
                        </div>
                    </section>

                    <section v-if="hasHistoryDetail(detailData)" class="apt-h5-detail-section">
                        <h3>病史信息</h3>
                        <div class="apt-h5-detail-grid">
                            <div v-if="isDiabetesDiscoveryFilled(detailData.diabetes_discovery_year)">
                                <span>发现糖尿病病史</span>
                                <strong>{{ formatDiabetesDiscoveryDisplay(detailData.diabetes_discovery_year) }}</strong>
                            </div>
                            <div v-if="detailData.local_hospital_name">
                                <span>当地就诊医院</span>
                                <strong>{{ detailData.local_hospital_name }}</strong>
                            </div>
                            <div v-if="detailData.symptoms" class="apt-h5-detail-full">
                                <span>症状补充</span>
                                <strong>{{ detailData.symptoms }}</strong>
                            </div>
                            <div v-if="detailData.past_history && detailData.past_history.length" class="apt-h5-detail-full">
                                <span>既往史</span>
                                <strong>{{ getPastHistoryLabels(detailData.past_history) }}</strong>
                            </div>
                        </div>
                    </section>

                    <section v-if="hasDiagnosisDetail(detailData)" class="apt-h5-detail-section">
                        <h3>诊断信息</h3>
                        <div class="apt-h5-detail-grid">
                            <div v-if="detailData.tongue_coating">
                                <span>舌苔</span>
                                <strong>{{ detailData.tongue_coating }}</strong>
                            </div>
                            <div v-if="detailData.pulse">
                                <span>脉象</span>
                                <strong>{{ detailData.pulse }}</strong>
                            </div>
                            <div v-if="detailData.treatment_principle" class="apt-h5-detail-full">
                                <span>治则</span>
                                <strong>{{ detailData.treatment_principle }}</strong>
                            </div>
                            <div v-if="detailData.prescription" class="apt-h5-detail-full">
                                <span>处方</span>
                                <strong>{{ detailData.prescription }}</strong>
                            </div>
                        </div>
                    </section>

                    <section class="apt-h5-detail-section">
                        <h3>备注</h3>
                        <p>{{ detailData.remark || '无' }}</p>
                    </section>
                </template>
            </main>

            <footer v-if="detailData" class="apt-h5-detail-footer-bar">
                <div class="apt-h5-detail-footer">
                    <el-button
                        v-if="hasPermission(['tcm.diagnosis/edit'])"
                        type="primary"
                        plain
                        @click="handleEdit(detailActionRow)"
                    >
                        编辑患者
                    </el-button>
                    <el-button
                        v-if="hasPermission(['tcm.diagnosis/kaifang'])"
                        type="primary"
                        @click="handlePrescription(detailActionRow)"
                    >
                        {{ prescriptionActionLabel(detailActionRow) }}
                    </el-button>
                    <el-button
                        v-if="detailActionRow.status !== 3 && hasPermission(['doctor.appointment/prescription'])"
                        type="primary"
                        plain
                        @click="handleChat(detailActionRow)"
                    >
                        通话
                    </el-button>
                    <el-button
                        v-if="detailActionRow.status !== 3 && hasPermission(['doctor.appointment/complete'])"
                        type="success"
                        plain
                        @click="handleComplete(detailActionRow)"
                    >
                        完成
                    </el-button>
                </div>
            </footer>
        </template>

        <el-dialog
            v-model="qrcodeDialogVisible"
            title="视频二维码"
            :close-on-click-modal="false"
            class="apt-h5-qr-dialog"
        >
            <div class="apt-h5-qr">
                <div v-if="qrcodeLoading" class="apt-h5-qr-loading">
                    <el-icon class="is-loading" :size="36"><Loading /></el-icon>
                    <div>生成中...</div>
                </div>
                <div v-else-if="qrcodeUrl">
                    <img :src="qrcodeUrl" alt="小程序二维码" class="apt-h5-qr-img" />
                    <div class="apt-h5-qr-meta">
                        <div>患者：{{ currentQRCodeRow?.patient_name || '-' }}</div>
                        <div>请使用微信扫描二维码</div>
                    </div>
                </div>
                <div v-else class="apt-h5-qr-fail">生成失败，请重试</div>
            </div>
            <template #footer>
                <el-button @click="qrcodeDialogVisible = false">关闭</el-button>
                <el-button v-if="!qrcodeLoading" type="primary" @click="handleRegenerateQRCode">重新生成</el-button>
            </template>
        </el-dialog>

        <el-dialog
            v-model="completeDialogVisible"
            title="完成问诊"
            :close-on-click-modal="false"
            class="apt-h5-complete-dialog"
            destroy-on-close
        >
            <div class="apt-h5-complete">
                <p>确认患者已就诊完成？</p>
                <el-input
                    v-if="canAddCompleteNote"
                    v-model="completeNoteContent"
                    type="textarea"
                    :rows="4"
                    maxlength="500"
                    show-word-limit
                    placeholder="填写完成备注，将追加到医生备注时间轴"
                />
            </div>
            <template #footer>
                <el-button @click="completeDialogVisible = false">取消</el-button>
                <el-button type="primary" :loading="completeSubmitting" @click="submitComplete">确认完成</el-button>
            </template>
        </el-dialog>

        <edit-popup ref="editRef" @success="() => loadData({ silent: true })" />
        <tcm-prescription ref="prescriptionRef" @success="onPrescriptionSuccess" />
        <chat-dialog ref="chatDialogRef" />
    </div>
</template>

<script setup lang="ts" name="tcmAppointmentH5">
import { appointmentDetail, appointmentLists, cancelAppointment, completeAppointment } from '@/api/doctor'
import { getWeappConfig } from '@/api/channel/weapp'
import {
    generateMiniProgramQrcode,
    getCallSignature,
    prescriptionGetByAppointment,
    tcmDiagnosisDetail
} from '@/api/tcm'
import { getDictData } from '@/api/app'
import { addDoctorNote } from '@/api/patient'
import { usePaging } from '@/hooks/usePaging'
import useUserStore from '@/stores/modules/user'
import {
    formatDiabetesDiscoveryDisplay,
    isDiabetesDiscoveryFilled
} from '@/utils/diabetes-discovery-display'
import feedback from '@/utils/feedback'
import { hasPermission } from '@/utils/perm'
import {
    ArrowDown,
    CircleCheck,
    CircleClose,
    Document,
    Loading,
    Phone,
    Picture,
    Search
} from '@element-plus/icons-vue'
import { computed, defineAsyncComponent, onMounted, onUnmounted, reactive, ref } from 'vue'

const EditPopup = defineAsyncComponent(() => import('../diagnosis/edit.vue'))
const TcmPrescription = defineAsyncComponent(() => import('@/components/tcm-prescription/index.vue'))
const ChatDialog = defineAsyncComponent(() => import('@/components/chat-dialog/index.vue'))

const userStore = useUserStore()
const userInfo = computed(() => userStore.userInfo)

const todayDate = () => {
    const t = new Date()
    return formatDate(t)
}
const formatDate = (date: Date) => {
    const pad = (n: number) => String(n).padStart(2, '0')
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
}
const dateByOffset = (offset: number) => {
    const t = new Date()
    t.setDate(t.getDate() + offset)
    return formatDate(t)
}
const maskPhone = (phone: string) => {
    if (!phone || phone.length < 11) return phone
    return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

const isAdmin = computed(() => {
    const roleId = userInfo.value?.role_id
    if (Array.isArray(roleId)) return !roleId.includes(1) && !roleId.includes(2)
    return roleId !== 1 && roleId !== 2
})

const formData = reactive({
    patient_name: '',
    doctor_name: '',
    status: 1 as string | number,
    start_date: todayDate(),
    end_date: todayDate(),
    date_preset: 'today' as '' | 'yesterday' | 'day_before' | 'today' | 'tomorrow' | 'day_after',
    diagnosis_confirmed: '' as '' | '0' | '1',
    include_status_counts: 0 as 0 | 1
})
const activeTab = ref('1')
const currentView = ref<'list' | 'detail'>('list')
const showMoreFilter = ref(false)
const customDateRange = ref<[string, string] | ''>('')
const statusCount = ref<Record<number, number>>({ 1: 0, 2: 0, 3: 0, 4: 0 })

const { pager, getLists } = usePaging({
    fetchFun: appointmentLists,
    params: formData,
    firstLoading: true
})

const statusTabs = computed(() => [
    { label: '待接诊', value: '1', count: statusCount.value[1] },
    { label: '全部', value: 'all', count: 0 },
    { label: '已过号', value: '4', count: statusCount.value[4] },
    { label: '已取消', value: '2', count: statusCount.value[2] },
    { label: '已完成', value: '3', count: statusCount.value[3] }
])
const dateTabs = [
    { label: '昨天', value: 'yesterday' },
    { label: '前天', value: 'day_before' },
    { label: '今天', value: 'today' },
    { label: '明天', value: 'tomorrow' },
    { label: '后天', value: 'day_after' },
    { label: '不限', value: '' }
] as const
const confirmedOptions = [
    { label: '全部', value: '' },
    { label: '已确认', value: '1' },
    { label: '未确认', value: '0' }
] as const
const hasMore = computed(() => pager.lists.length < (pager.count || 0))

const loadData = async (opts?: { silent?: boolean }) => {
    formData.include_status_counts = 1
    try {
        await getLists(opts)
        const sc = (pager.extend as { status_count?: Record<string | number, number> })?.status_count
        if (sc) {
            ;([1, 2, 3, 4] as const).forEach((key) => {
                const n = sc[key] ?? sc[String(key)]
                statusCount.value[key] = typeof n === 'number' ? n : 0
            })
        }
    } finally {
        formData.include_status_counts = 0
    }
}

const handleSearch = () => {
    pager.page = 1
    loadData()
}
const handleTabChange = (tab: string) => {
    activeTab.value = tab
    formData.status = tab === 'all' ? '' : Number(tab)
    pager.page = 1
    loadData()
}
const handleDatePresetChange = (value: string) => {
    formData.date_preset = value as typeof formData.date_preset
    customDateRange.value = ''
    if (!value) {
        formData.start_date = ''
        formData.end_date = ''
    } else {
        const offsetMap: Record<string, number> = {
            yesterday: -1,
            day_before: -2,
            today: 0,
            tomorrow: 1,
            day_after: 2
        }
        const date = dateByOffset(offsetMap[value] ?? 0)
        formData.start_date = date
        formData.end_date = date
    }
    pager.page = 1
    loadData()
}
const handleConfirmedChange = (value: '' | '0' | '1') => {
    formData.diagnosis_confirmed = value
    pager.page = 1
    loadData()
}
const applyCustomDate = () => {
    if (!customDateRange.value) {
        handleDatePresetChange('')
        return
    }
    formData.date_preset = ''
    formData.start_date = customDateRange.value[0]
    formData.end_date = customDateRange.value[1]
    pager.page = 1
    loadData()
}
const handleReset = () => {
    formData.patient_name = ''
    formData.doctor_name = ''
    formData.diagnosis_confirmed = ''
    activeTab.value = '1'
    formData.status = 1
    handleDatePresetChange('today')
}
const loadMore = async () => {
    if (pager.loading || !hasMore.value) return
    const next = (pager.page || 1) + 1
    pager.loading = true
    try {
        const res = await appointmentLists({
            page_no: next,
            page_size: pager.size,
            ...formData,
            include_status_counts: 0
        })
        pager.page = next
        pager.lists.push(...(res?.lists || []))
        pager.count = res?.count ?? pager.count
    } finally {
        pager.loading = false
    }
}

const statusLabel = (status: number | string) => {
    const s = Number(status)
    if (s === 1) return '待接诊'
    if (s === 2) return '已取消'
    if (s === 3) return '已完成'
    if (s === 4) return '已过号'
    return '-'
}
const statusTagClass = (status: number | string) => {
    const s = Number(status)
    return {
        'apt-h5-tag--ok': s === 1 || s === 3,
        'apt-h5-tag--gray': s === 2,
        'apt-h5-tag--danger': s === 4
    }
}
const cardClass = (row: any) => ({
    'apt-h5-card--done': Number(row.status) === 3,
    'apt-h5-card--cancel': Number(row.status) === 2,
    'apt-h5-card--missed': Number(row.status) === 4
})

const editRef = ref()
const prescriptionRef = ref()
const chatDialogRef = ref()
const COMPLETE_NOTE_PERMISSION = ['doctor.appointment/addDoctorNote']
const completeDialogVisible = ref(false)
const completeSubmitting = ref(false)
const completeNoteContent = ref('')
const completeRow = ref<any>(null)
const canAddCompleteNote = computed(() => hasPermission(COMPLETE_NOTE_PERMISSION))

const handleEdit = (row: any) => {
    if (!row.patient_id) {
        feedback.msgWarning('该预约没有关联诊单信息')
        return
    }
    editRef.value?.open('edit', row.patient_id)
}
const handleChat = async (row: any) => {
    if (!row.patient_id) {
        feedback.msgWarning('患者信息不完整')
        return
    }
    try {
        const res = await getCallSignature({
            patient_id: row.patient_id,
            diagnosis_id: row.diagnosis_id || row.id
        })
        chatDialogRef.value?.open({
            patientId: row.patient_id,
            patientName: row.patient_name,
            diagnosisId: row.diagnosis_id || row.id,
            signatureData: res
        })
    } catch (e: any) {
        feedback.msgError(e?.msg || e?.message || '获取通话签名失败')
    }
}
const prescriptionActionLabel = (row: any) => {
    if (row?.prescription_audit_status === 1 && Number(row?.prescription_void_status) !== 1) return '查看'
    return '开方'
}
const handlePrescription = (row: any) => {
    if (!row.diagnosis_id && !row.patient_id) {
        feedback.msgWarning('该预约缺少诊单信息，请先编辑患者')
        return
    }
    prescriptionRef.value?.open(row)
}
const onPrescriptionSuccess = () => {
    loadData()
    editRef.value?.refreshCaseList?.()
}

const moreSheetVisible = ref(false)
const moreSheetRow = ref<any>(null)
const openMoreSheet = (row: any) => {
    moreSheetRow.value = row
    moreSheetVisible.value = true
}
const runAction = (cmd: string) => {
    const row = moreSheetRow.value
    moreSheetVisible.value = false
    if (!row) return
    if (cmd === 'videoQr') handleMiniProgramQRCode(row)
    if (cmd === 'complete') handleComplete(row)
    if (cmd === 'case') handleViewCase(row)
    if (cmd === 'cancel') handleCancel(row)
}
const handleComplete = async (row: any) => {
    completeRow.value = row
    completeNoteContent.value = ''
    if (canAddCompleteNote.value) {
        completeDialogVisible.value = true
        return
    }
    try {
        await feedback.confirm('确认患者已就诊完成？')
        await completeAppointment({ id: row.id })
        feedback.msgSuccess('操作成功')
        loadData()
    } catch (e: any) {
        if (e !== 'cancel') feedback.msgError(e?.msg || '操作失败')
    }
}
const submitComplete = async () => {
    const row = completeRow.value
    if (!row?.id || completeSubmitting.value) return
    completeSubmitting.value = true
    try {
        const note = completeNoteContent.value.trim()
        await completeAppointment({ id: row.id })
        let noteFailureMsg = ''
        if (canAddCompleteNote.value && note) {
            const diagnosisId = row.patient_id || row.diagnosis_id
            if (diagnosisId) {
                try {
                    await addDoctorNote({ diagnosis_id: Number(diagnosisId), content: note })
                } catch (e) {
                    noteFailureMsg = '问诊已完成，但备注未保存'
                }
            } else {
                noteFailureMsg = '问诊已完成，但该预约没有关联诊单，备注未保存'
            }
        }
        noteFailureMsg ? feedback.msgWarning(noteFailureMsg) : feedback.msgSuccess('操作成功')
        completeDialogVisible.value = false
        completeNoteContent.value = ''
        completeRow.value = null
        if (currentView.value === 'detail') {
            backToList()
        }
        loadData()
    } catch (e: any) {
        feedback.msgError(e?.msg || e?.message || '操作失败')
    } finally {
        completeSubmitting.value = false
    }
}
const handleCancel = async (row: any) => {
    try {
        await feedback.confirm('确定要取消该挂号吗？')
        await cancelAppointment({ id: row.id })
        feedback.msgSuccess('取消成功')
        loadData()
    } catch (e: any) {
        if (e !== 'cancel') feedback.msgError(e?.msg || '取消失败')
    }
}
const handleViewCase = async (row: any) => {
    try {
        const prescription = await prescriptionGetByAppointment({ appointment_id: row.id })
        if (prescription?.id) {
            prescriptionRef.value?.openById(prescription.id)
        } else {
            feedback.msgWarning('该预约暂无病历记录，请先开方')
        }
    } catch (e: any) {
        feedback.msgError(e?.msg || '获取病历失败')
    }
}

const qrcodeDialogVisible = ref(false)
const qrcodeLoading = ref(false)
const qrcodeUrl = ref('')
const currentQRCodeRow = ref<any>(null)
const handleMiniProgramQRCode = async (row: any) => {
    if (!row.patient_id) {
        feedback.msgWarning('患者信息不完整')
        return
    }
    currentQRCodeRow.value = row
    qrcodeDialogVisible.value = true
    qrcodeLoading.value = true
    qrcodeUrl.value = ''
    try {
        const config = await getWeappConfig()
        if (!config?.app_id) {
            feedback.msgError('小程序未配置，请先配置小程序信息')
            qrcodeDialogVisible.value = false
            return
        }
        const result = await generateMiniProgramQrcode({
            diagnosis_id: row.doctor_id || '',
            patient_id: row.patient_id,
            share_user_id: userStore.userInfo?.id || '',
            mini_program_path: 'pages/login/login'
        })
        if (result?.qrcode_url) qrcodeUrl.value = result.qrcode_url
        else feedback.msgError('二维码生成失败')
    } catch (e: any) {
        feedback.msgError(e?.msg || '生成二维码失败，请重试')
    } finally {
        qrcodeLoading.value = false
    }
}
const handleRegenerateQRCode = () => {
    if (currentQRCodeRow.value) handleMiniProgramQRCode(currentQRCodeRow.value)
}

const detailLoading = ref(false)
const detailData = ref<any>(null)
const detailSourceRow = ref<any>(null)
const detailActionRow = computed(() => ({ ...(detailSourceRow.value || {}), ...(detailData.value || {}) }))
const diagnosisTypeOptions = ref<any[]>([])
const syndromeTypeOptions = ref<any[]>([])
const diabetesTypeOptions = ref<any[]>([])
const pastHistoryOptions = ref<any[]>([])
const detailDictReady = ref(false)

const getDictLabel = (options: any[], value: string) => {
    if (!value) return '-'
    const item = options.find((opt: any) => opt.value === value)
    return item ? item.name : value
}
const getPastHistoryLabels = (values: string[] | string) => {
    const arr = Array.isArray(values) ? values : typeof values === 'string' ? values.split(/[,，、]/) : []
    return arr.map((v: string) => getDictLabel(pastHistoryOptions.value, v.trim())).filter(Boolean).join('、') || '-'
}
const maritalStatusLabel = (value: number | string | undefined) => {
    if (Number(value) === 0) return '未婚'
    if (Number(value) === 1) return '已婚'
    if (Number(value) === 2) return '离异'
    return '-'
}
const loadDetailDictOptions = async () => {
    const [dt, st, db, ph] = await Promise.all([
        getDictData({ type: 'diagnosis_type' }),
        getDictData({ type: 'syndrome_type' }),
        getDictData({ type: 'diabetes_type' }),
        getDictData({ type: 'past_history' })
    ])
    diagnosisTypeOptions.value = dt?.diagnosis_type || []
    syndromeTypeOptions.value = st?.syndrome_type || []
    diabetesTypeOptions.value = db?.diabetes_type || []
    pastHistoryOptions.value = ph?.past_history || []
}
const ensureDetailDictOptions = async () => {
    if (detailDictReady.value) return
    await loadDetailDictOptions()
    detailDictReady.value = true
}
const hasHistoryDetail = (data: any) =>
    isDiabetesDiscoveryFilled(data?.diabetes_discovery_year) ||
    !!data?.local_hospital_name ||
    !!data?.symptoms ||
    (Array.isArray(data?.past_history) ? data.past_history.length > 0 : !!data?.past_history)
const hasDiagnosisDetail = (data: any) =>
    !!(data?.tongue_coating || data?.pulse || data?.treatment_principle || data?.prescription)

const handleDetail = async (row: any) => {
    currentView.value = 'detail'
    detailLoading.value = true
    detailData.value = null
    detailSourceRow.value = row
    try {
        const [, appointment] = await Promise.all([
            ensureDetailDictOptions().catch((e) => console.warn('加载详情字典失败:', e)),
            appointmentDetail({ id: row.id })
        ])
        detailData.value = { ...row, ...appointment, appointment_id: row.id }
        if (appointment?.patient_id) {
            try {
                const diagnosis = await tcmDiagnosisDetail({ id: appointment.patient_id })
                detailData.value = {
                    ...row,
                    ...appointment,
                    ...diagnosis,
                    id: appointment.id || row.id,
                    appointment_id: row.id,
                    diagnosis_id: appointment.patient_id
                }
            } catch (e) {
                console.warn('获取患者诊单详情失败:', e)
            }
        }
    } catch (e: any) {
        feedback.msgError(e?.msg || '获取详情失败')
        currentView.value = 'list'
    } finally {
        detailLoading.value = false
    }
}
const backToList = () => {
    currentView.value = 'list'
    detailLoading.value = false
}

const LIST_POLL_MS = 20_000
let listPollTimer: ReturnType<typeof setInterval> | null = null

onMounted(() => {
    document.body.classList.add('h5-mode')
    loadData()
    listPollTimer = setInterval(() => {
        loadData({ silent: true }).catch(() => undefined)
    }, LIST_POLL_MS)
})

onUnmounted(() => {
    document.body.classList.remove('h5-mode')
    if (listPollTimer !== null) {
        clearInterval(listPollTimer)
        listPollTimer = null
    }
})
</script>

<style scoped lang="scss">
.apt-h5 {
    max-width: 560px;
    margin: 0 auto;
    min-height: 100vh;
    background: #f5f7fb;
    color: #1f2937;
    padding-bottom: 24px;
    -webkit-font-smoothing: antialiased;
}

.apt-h5-topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    padding: 12px 12px 10px;
    background: rgba(245, 247, 251, 0.96);
    border-bottom: 1px solid #e5e7eb;
    backdrop-filter: blur(8px);
}

.apt-h5-search {
    display: flex;
    gap: 8px;
}

.apt-h5-search :deep(.el-input__wrapper) {
    border-radius: 8px;
}

.apt-h5-search-btn {
    flex: 0 0 72px;
    border-radius: 8px;
}

.apt-h5-scroll {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding: 10px 0 0;
    scrollbar-width: none;
}

.apt-h5-scroll::-webkit-scrollbar {
    display: none;
}

.apt-h5-chip,
.apt-h5-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    min-height: 30px;
    padding: 0 12px;
    border: 1px solid #d8dee8;
    border-radius: 8px;
    background: #fff;
    color: #4b5563;
    font-size: 13px;
    line-height: 1;
}

.apt-h5-chip em {
    min-width: 18px;
    height: 18px;
    margin-left: 5px;
    padding: 0 5px;
    border-radius: 9px;
    background: #eef2ff;
    color: #2563eb;
    font-style: normal;
    font-size: 11px;
    line-height: 18px;
    text-align: center;
}

.apt-h5-chip.active,
.apt-h5-pill.active {
    border-color: #2563eb;
    background: #2563eb;
    color: #fff;
}

.apt-h5-chip.active em {
    background: rgba(255, 255, 255, 0.2);
    color: #fff;
}

.apt-h5-quick {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding-top: 10px;
}

.apt-h5-quick-group {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.apt-h5-quick-group::-webkit-scrollbar {
    display: none;
}

.apt-h5-quick-label {
    flex: 0 0 auto;
    color: #6b7280;
    font-size: 12px;
}

.apt-h5-more-toggle {
    flex: 0 0 auto;
}

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

.apt-h5-more-filter {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    padding-top: 10px;
}

.apt-h5-date-range {
    width: 100% !important;
}

.apt-h5-list {
    min-height: calc(100vh - 150px);
    padding: 12px;
}

.apt-h5-empty {
    margin-top: 48px;
}

.apt-h5-card {
    margin-bottom: 10px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #fff;
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.05);
    overflow: hidden;
}

.apt-h5-card--missed {
    border-color: #fecaca;
}

.apt-h5-card--cancel,
.apt-h5-card--done {
    opacity: 0.86;
}

.apt-h5-card-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 12px 10px;
}

.apt-h5-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: #eff6ff;
    color: #2563eb;
    font-weight: 600;
}

.apt-h5-title {
    min-width: 0;
    flex: 1;
}

.apt-h5-name {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    color: #111827;
    font-size: 16px;
    font-weight: 600;
    line-height: 22px;
}

.apt-h5-meta {
    color: #6b7280;
    font-size: 12px;
    font-weight: 400;
}

.apt-h5-sub {
    margin-top: 3px;
    color: #8a94a6;
    font-size: 12px;
}

.apt-h5-tags {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 5px;
    flex: 0 0 auto;
}

.apt-h5-tag,
.apt-h5-inline-tag {
    display: inline-flex;
    align-items: center;
    min-height: 22px;
    padding: 0 7px;
    border-radius: 6px;
    background: #eef2f7;
    color: #64748b;
    font-size: 12px;
}

.apt-h5-tag--ok,
.apt-h5-inline-tag--ok {
    background: #ecfdf3;
    color: #15803d;
}

.apt-h5-tag--warn,
.apt-h5-inline-tag--warn {
    background: #fff7ed;
    color: #c2410c;
}

.apt-h5-tag--danger {
    background: #fef2f2;
    color: #dc2626;
}

.apt-h5-tag--gray {
    background: #f3f4f6;
    color: #6b7280;
}

.apt-h5-card-body {
    padding: 0 12px 10px;
}

.apt-h5-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 5px 0;
    font-size: 13px;
    line-height: 20px;
}

.apt-h5-row-key {
    flex: 0 0 38px;
    color: #8a94a6;
}

.apt-h5-row-val {
    min-width: 0;
    flex: 1;
    color: #374151;
    word-break: break-word;
}

.apt-h5-row--remark .apt-h5-row-val {
    color: #6b7280;
}

.apt-h5-card-foot {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 7px;
    padding: 10px 12px 12px;
    border-top: 1px solid #f1f5f9;
}

.apt-h5-card-foot :deep(.el-button) {
    min-width: 0;
    margin: 0;
    border-radius: 8px;
}

.apt-h5-more-btn {
    color: #4b5563;
}

.apt-h5-load-more,
.apt-h5-no-more {
    padding: 14px 0 18px;
    color: #6b7280;
    font-size: 13px;
    text-align: center;
}

.apt-h5-load-more {
    color: #2563eb;
}

.apt-h5-actions {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    padding: 4px 4px 16px;
}

.apt-h5-action {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 72px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #fff;
    color: #374151;
    font-size: 12px;
}

.apt-h5-action :deep(.el-icon) {
    font-size: 22px;
    color: #2563eb;
}

.apt-h5-action--danger {
    color: #dc2626;
}

.apt-h5-action--danger :deep(.el-icon) {
    color: #dc2626;
}

.apt-h5-detail-topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 10px;
    min-height: 54px;
    padding: 8px 12px;
    border-bottom: 1px solid #e5e7eb;
    background: rgba(245, 247, 251, 0.98);
    backdrop-filter: blur(8px);
}

.apt-h5-back {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    height: 36px;
    padding: 0 8px 0 4px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #2563eb;
    font-size: 14px;
}

.apt-h5-back span {
    font-size: 26px;
    line-height: 1;
    transform: translateY(-1px);
}

.apt-h5-detail-title {
    min-width: 0;
}

.apt-h5-detail-title strong,
.apt-h5-detail-title small {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.apt-h5-detail-title strong {
    color: #111827;
    font-size: 16px;
    line-height: 22px;
}

.apt-h5-detail-title small {
    margin-top: 1px;
    color: #8a94a6;
    font-size: 12px;
}

.apt-h5-detail-page {
    min-height: calc(100vh - 54px);
    padding: 12px 12px 82px;
}

.apt-h5-detail-section {
    margin-bottom: 12px;
    padding: 12px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #fff;
}

.apt-h5-detail-section h3 {
    margin: 0 0 10px;
    color: #111827;
    font-size: 15px;
    font-weight: 600;
}

.apt-h5-detail-section p {
    margin: 0 0 8px;
    color: #4b5563;
    font-size: 13px;
    line-height: 20px;
}

.apt-h5-detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

.apt-h5-detail-grid div {
    min-width: 0;
}

.apt-h5-detail-grid .apt-h5-detail-full {
    grid-column: 1 / -1;
}

.apt-h5-detail-grid span {
    display: block;
    margin-bottom: 3px;
    color: #8a94a6;
    font-size: 12px;
}

.apt-h5-detail-grid strong {
    display: block;
    color: #374151;
    font-size: 13px;
    font-weight: 500;
    word-break: break-word;
}

.apt-h5-detail-footer {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    width: 100%;
}

.apt-h5-detail-footer-bar {
    position: sticky;
    bottom: 0;
    z-index: 20;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    border-top: 1px solid #e5e7eb;
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(8px);
}

.apt-h5-detail-footer :deep(.el-button) {
    min-width: 0;
    margin: 0;
    border-radius: 8px;
}

.apt-h5-qr {
    min-height: 160px;
    text-align: center;
}

.apt-h5-qr-loading,
.apt-h5-qr-fail {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 160px;
    color: #6b7280;
    gap: 10px;
}

.apt-h5-qr-img {
    width: 220px;
    height: 220px;
    margin: 0 auto;
}

.apt-h5-qr-meta {
    margin-top: 10px;
    color: #6b7280;
    font-size: 13px;
    line-height: 22px;
}

.apt-h5-complete p {
    margin: 0 0 12px;
    color: #374151;
    font-size: 14px;
    line-height: 22px;
}

.apt-h5-complete :deep(.el-textarea__inner) {
    min-height: 112px !important;
    border-radius: 8px;
}

@media (max-width: 374px) {
    .apt-h5-card-foot {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .apt-h5-actions {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
</style>

<style lang="scss">
body.h5-mode {
    background: #eef2f7;

    .el-drawer {
        width: min(100vw, 560px) !important;
        max-width: 560px !important;
    }

    .el-drawer.rtl {
        right: max(0px, calc((100vw - 560px) / 2)) !important;
    }

    .el-drawer.ltr {
        left: max(0px, calc((100vw - 560px) / 2)) !important;
    }

    .el-drawer.btt,
    .el-drawer.ttb {
        left: 50% !important;
        right: auto !important;
        transform: translateX(-50%) !important;
    }

    .el-drawer__body {
        padding: 0 14px 14px !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    .el-drawer__header {
        padding: 14px 16px !important;
        margin-bottom: 0 !important;
        border-bottom: 1px solid #eee;
        background: #fff;

        .el-drawer__title {
            font-size: 17px;
            font-weight: 600;
        }
    }

    .el-drawer__footer {
        padding: 10px 16px !important;
        border-top: 1px solid #eee;
        background: #fff;
    }

    .el-overlay-dialog .el-dialog,
    .el-dialog {
        width: 92% !important;
        max-width: 460px !important;
        margin: 8vh auto !important;
        border-radius: 12px !important;
    }

    .el-dialog__body {
        max-height: 65vh;
        overflow-y: auto;
    }

    .edit-drawer {
        .el-row {
            display: block !important;
            margin-left: 0 !important;
            margin-right: 0 !important;
        }

        .el-col {
            max-width: 100% !important;
            flex: 0 0 100% !important;
            width: 100% !important;
            padding-left: 0 !important;
            padding-right: 0 !important;
        }
    }

    .diagnosis-drawer {
        .el-drawer__body { padding-bottom: 60px !important; }

        .el-form {
            padding-bottom: 10px;

            .el-form-item {
                flex-direction: column !important;
                align-items: flex-start !important;
                margin-bottom: 10px !important;
                padding: 0 !important;

                .el-form-item__label {
                    width: auto !important;
                    max-width: 100% !important;
                    min-width: 0 !important;
                    text-align: left !important;
                    padding: 0 0 3px 0 !important;
                    font-size: 14px !important;
                    font-weight: 500;
                    color: #475569;
                    line-height: 1.4 !important;
                    height: auto !important;
                    justify-content: flex-start !important;
                }

                .el-form-item__content {
                    margin-left: 0 !important;
                    width: 100% !important;
                }
            }
        }

        .el-divider {
            margin: 18px 0 12px !important;

            .el-divider__text {
                max-width: calc(100% - 32px);
                padding: 0 8px !important;
                color: #0f172a;
                font-size: 15px;
                font-weight: 700;
                white-space: nowrap;
            }
        }

        .checkbox-form-item {
            margin-bottom: 14px !important;
        }

        .el-radio-group,
        .el-checkbox-group {
            display: grid !important;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 8px;
            width: 100%;
            align-items: stretch;
        }

        .checkbox-form-item .el-checkbox-group {
            grid-template-columns: repeat(3, minmax(0, 1fr));
        }

        .el-radio,
        .el-checkbox,
        .el-radio-button,
        .el-checkbox-button {
            width: 100%;
            height: auto !important;
            margin: 0 !important;
            white-space: normal !important;
        }

        .el-radio__label,
        .el-checkbox__label {
            white-space: normal !important;
            line-height: 18px !important;
        }

        .el-radio-button__inner,
        .el-checkbox-button__inner {
            display: flex !important;
            align-items: center;
            justify-content: center;
            width: 100% !important;
            min-height: 34px;
            padding: 7px 8px !important;
            border: 1px solid #d8dee8 !important;
            border-radius: 8px !important;
            box-shadow: none !important;
            white-space: normal !important;
            line-height: 18px !important;
            text-align: center;
        }

        .el-radio-button:first-child .el-radio-button__inner,
        .el-checkbox-button:first-child .el-checkbox-button__inner,
        .el-radio-button:last-child .el-radio-button__inner,
        .el-checkbox-button:last-child .el-checkbox-button__inner {
            border-radius: 8px !important;
        }

        .el-radio-button.is-active .el-radio-button__inner,
        .el-checkbox-button.is-checked .el-checkbox-button__inner {
            border-color: #2563eb !important;
            background: #2563eb !important;
            color: #fff !important;
        }

        @media (max-width: 430px) {
            .checkbox-form-item .el-checkbox-group {
                grid-template-columns: repeat(2, minmax(0, 1fr));
            }
        }
    }

    .tcm-diagnosis-tabs {
        .el-tabs__header {
            margin: 0 0 10px !important;
        }

        .el-tabs__nav-wrap {
            overflow-x: auto;
        }
    }

    .tcm-dd-header__title {
        font-size: 17px !important;
        line-height: 24px !important;
    }

    .prescription-edit,
    .prescription-preview-content {
        max-width: 100%;
        overflow-x: hidden;

        .el-row {
            display: block !important;
            margin-left: 0 !important;
            margin-right: 0 !important;
        }

        .el-col {
            max-width: 100% !important;
            flex: 0 0 100% !important;
            width: 100% !important;
            padding-left: 0 !important;
            padding-right: 0 !important;
        }

        .el-form-item {
            display: block !important;
            margin-bottom: 10px !important;

            .el-form-item__label {
                display: block !important;
                width: auto !important;
                height: auto !important;
                padding: 0 0 4px !important;
                line-height: 1.4 !important;
                text-align: left !important;
            }

            .el-form-item__content {
                margin-left: 0 !important;
                width: 100% !important;
            }
        }

        .info-section {
            padding: 12px !important;
            margin-bottom: 12px !important;
            border-radius: 8px !important;
        }

        .rp-toolbar,
        .rp-toolbar__lead,
        .rp-toolbar__actions,
        .herb-editor-card__row,
        .usage-formula-row {
            display: block !important;
        }

        .rp-toolbar__actions {
            margin-top: 10px;

            .el-button {
                width: 100%;
                margin: 0 0 8px !important;
            }
        }

        .herbs-editor-grid {
            display: grid !important;
            grid-template-columns: 1fr !important;
            gap: 8px !important;
        }

        .herb-editor-card,
        .herb-editor-card__select,
        .herb-editor-card__dose,
        .el-input-number,
        .el-select,
        .el-input,
        .el-textarea {
            width: 100% !important;
            max-width: 100% !important;
        }

        .herb-editor-card__row {
            .el-button {
                margin-top: 6px;
            }
        }
    }

    .chat-floating-window {
        position: fixed !important;
        right: max(0px, calc((100vw - 560px) / 2)) !important;
        bottom: 0 !important;
        left: auto !important;
        top: auto !important;
        width: min(100vw, 560px) !important;
        height: min(76vh, 680px) !important;
        max-width: 560px !important;
        border-radius: 12px 12px 0 0 !important;
        transform: none !important;
        z-index: 3000 !important;
    }

    .chat-floating-window--minimized {
        height: 48px !important;
    }

    .chat-window-header {
        min-height: 48px;
        padding: 0 10px !important;
    }

    .chat-window-title {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .chat-container,
    .chat-content,
    .chat-layout,
    .chat-area {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
    }

    .chat-container {
        height: calc(76vh - 48px) !important;
    }

    .chat-dialog-call-kit-wrapper {
        left: 50% !important;
        right: auto !important;
        top: 8px !important;
        width: min(100vw, 560px) !important;
        max-width: 560px !important;
        transform: translateX(-50%) !important;
    }

    .call-kit-content {
        width: 100% !important;
        max-width: 100vw !important;
        overflow: hidden;
    }

    @media (max-width: 560px) {
        .el-drawer {
            width: 100% !important;
            max-width: 100vw !important;
        }

        .el-drawer.rtl {
            right: 0 !important;
        }

        .el-drawer.ltr,
        .el-drawer.btt,
        .el-drawer.ttb {
            left: 0 !important;
            transform: none !important;
        }

        .chat-floating-window {
            right: 0 !important;
            width: 100vw !important;
            max-width: 100vw !important;
        }

        .chat-dialog-call-kit-wrapper {
            width: 100vw !important;
            max-width: 100vw !important;
        }
    }
}
</style>
