<template>
	<view class="chat-page">
		<view class="chat-header">
			<view class="chat-header__row">
				<view class="fe-nav-btn guide-target guide-target--sidebar" @tap="openSidebar">
					<text class="fe-nav-icon">☰</text>
				</view>
				<text class="chat-header__title">智能用工助手</text>
				<view class="chat-header__actions">
					<view class="fe-nav-btn guide-target guide-target--new-chat" @tap="newChat">
						<text class="fe-nav-icon fe-nav-icon--plus">+</text>
					</view>
					<view class="fe-nav-btn guide-target guide-target--message" @tap="openDrawer('message')">
						<text class="fe-nav-icon">🔔</text>
						<view class="fe-nav-badge">2</view>
					</view>
					<view class="fe-nav-avatar guide-target guide-target--avatar" @tap="openDrawer('profile')">{{ user.avatarText }}</view>
				</view>
			</view>
		</view>

		<!-- Sidebar -->
		<view class="fe-sidebar" :class="{ 'fe-sidebar--open': sidebarOpen }">
			<view class="sidebar-head">
				<text class="sidebar-head__title">对话列表</text>
				<view class="sidebar-head__add" @tap="newChat">＋</view>
			</view>
			<scroll-view scroll-y class="sidebar-list" :show-scrollbar="false">
				<view v-if="sessionsLoading" class="sidebar-status">
					<text class="sidebar-status__text">加载中...</text>
				</view>
				<view v-else-if="!sessions.length" class="sidebar-status sidebar-status--action" @tap="newChat">
					<text class="sidebar-status__text sidebar-status__text--action">开启新对话</text>
				</view>
				<block v-else>
					<view
						v-for="(s, sessionIdx) in sessions"
						:key="s.conversationNo"
						class="fe-sidebar-item"
						:class="{ 'fe-sidebar-item--active': currentSession === s.conversationNo }"
						@tap="switchSessionByIndex(sessionIdx)"
					>
						<view class="fe-sidebar-item__title">{{ s.title }}</view>
						<view class="fe-sidebar-item__time">{{ s.time }}</view>
					</view>
				</block>
			</scroll-view>
		</view>

		<!-- Chat Area -->
		<scroll-view
			class="chat-area"
			scroll-y
			:scroll-top="scrollTop"
			:scroll-into-view="scrollIntoView"
			:scroll-with-animation="scrollWithAnimation"
			:show-scrollbar="false"
			:enhanced="true"
			:upper-threshold="80"
			@scroll="onChatScroll"
			@scrolltoupper="onChatScrollToUpper"
		>
			<view class="chat-area__inner">
				<view v-if="showNewChatEmpty" class="chat-empty">
					<view class="chat-empty__icon">💬</view>
					<text class="chat-empty__title">{{ newChatGreeting }}</text>
					<view class="chat-empty__btn" @tap="newChat">开启新对话</view>
				</view>
				<block v-else>
				<view v-if="messagesLoading" class="chat-status">
					<text class="chat-status__text">加载消息中...</text>
				</view>
				<block v-else>
				<view v-if="messagesLoadingMore" class="chat-status chat-status--top">
					<text class="chat-status__text">加载历史消息...</text>
				</view>
				<view v-else-if="!hasMoreHistory && hasMessageHistory" class="chat-status chat-status--top">
					<text class="chat-status__text chat-status__text--muted">没有更多消息了</text>
				</view>
				<view v-for="(msg, idx) in messages" :key="msg.msgKey" class="chat-msg-wrap">
					<!-- Plain text -->
					<view v-if="msg.type === 'text'" class="fe-chat-msg" :class="'fe-chat-msg--' + msg.role" :id="'msg-' + idx">
						<view v-if="msg.role === 'ai'" class="fe-chat-avatar fe-chat-avatar--ai">AI</view>
						<view v-if="msg.role === 'user'" class="fe-chat-avatar fe-chat-avatar--user">{{ user.avatarText }}</view>
						<view class="fe-chat-bubble">
							<view v-if="msg.streaming && !msg.content" class="fe-thinking-dots fe-thinking-dots--inline">
								<view class="fe-thinking-dots__dot" />
								<view class="fe-thinking-dots__dot" />
								<view class="fe-thinking-dots__dot" />
							</view>
							<view v-else class="fe-chat-bubble__text-wrap">
								<text class="fe-chat-bubble__text" user-select>{{ msg.content }}</text>
							</view>
						</view>
					</view>

					<!-- Report card -->
					<view v-else-if="msg.type === 'report'" class="fe-chat-msg fe-chat-msg--ai report-card-anchor" :id="'msg-' + idx">
						<view class="fe-chat-avatar fe-chat-avatar--ai">AI</view>
						<view class="fe-chat-bubble">
							<view class="fe-biz-card fe-biz-card--report" @tap="openSheet('report')">
								<view class="fe-biz-card__header">📊 今日汇报</view>
								<view class="fe-biz-card__row"><text>1. 浦东仓库</text><text class="fe-biz-card__val">8/10 人已登记</text></view>
								<view class="fe-biz-card__row"><text>2. 王五实名失败</text><text class="fe-biz-card__val fe-biz-card__val--danger">已自动提醒</text></view>
								<view class="fe-biz-card__row"><text>3. 结算单待确认</text><text class="fe-biz-card__val">¥12,800</text></view>
								<view class="fe-biz-card__actions">
									<view class="fe-biz-btn" @tap.stop="toast('已发送催办')">一键催办</view>
									<view class="fe-biz-btn" @tap.stop="openSheet('progress')">查看进度</view>
								</view>
							</view>
						</view>
					</view>

					<!-- Draft card -->
					<view v-else-if="msg.type === 'draft'" class="fe-chat-msg fe-chat-msg--ai" :id="'msg-' + idx">
						<view class="fe-chat-avatar fe-chat-avatar--ai">AI</view>
						<view class="fe-chat-bubble">
							<view class="fe-biz-card fe-biz-card--draft" :class="{ 'fe-biz-card--draft-confirmed': isDraftConfirmedByIndex(idx) }" @tap="openDraftByIndex(idx)">
								<view class="fe-biz-card__header">
									<text class="fe-biz-card__header-title">📄 {{ (msg.draft && msg.draft.title) || '用工草稿' }}</text>
									<text
										class="fe-draft-card-status"
										:class="isDraftConfirmedByIndex(idx) ? 'fe-draft-card-status--confirmed' : 'fe-draft-card-status--pending'"
									>{{ draftCardStatusLabelByIndex(idx) }}</text>
								</view>
								<view class="fe-biz-card__row">
									<text>岗位类型</text>
									<text class="fe-biz-card__val">{{ (msg.draft && msg.draft.workType) || '待补充' }}</text>
								</view>
								<view class="fe-biz-card__row">
									<text>工作地点</text>
									<text class="fe-biz-card__val">{{ (msg.draft && msg.draft.workLocation) || '待补充' }}</text>
								</view>
								<view class="fe-biz-card__row">
									<text>用工人数</text>
									<text class="fe-biz-card__val">{{ (msg.draft && msg.draft.headcountText) || '待补充' }}</text>
								</view>
								<view class="fe-draft-price">
									{{ (msg.draft && msg.draft.estimatedTotalText) || '—' }}
									<text style="font-size:26rpx;font-weight:500;color:#64748B;">预估总价</text>
								</view>
								<view class="fe-biz-card__actions fe-biz-card__actions--draft">
									<view class="fe-biz-btn fe-biz-btn--primary" @tap.stop="openDraftByIndex(idx)">查看详情</view>
									<text class="fe-biz-card__hint">如需修改草稿，请直接在对话中说明</text>
								</view>
							</view>
						</view>
					</view>

					<!-- Orders -->
					<view v-else-if="msg.type === 'orders'" class="fe-chat-msg fe-chat-msg--ai" :id="'msg-' + idx">
						<view class="fe-chat-avatar fe-chat-avatar--ai">AI</view>
						<view class="fe-chat-bubble">
							<view class="fe-biz-card" style="margin-bottom:16rpx;">
								<view class="fe-biz-card__header">📋 订单 #2024-001 · 活动执行</view>
								<view class="fe-biz-card__row"><text>状态</text><text class="fe-biz-card__val" style="color:#10B981;">进行中</text></view>
								<view class="fe-biz-card__row"><text>人数/时间</text><text class="fe-biz-card__val">10人 · 01-20至21</text></view>
								<view class="fe-biz-card__row"><text>已登记</text><text class="fe-biz-card__val">7/10人</text></view>
							</view>
							<view class="fe-biz-card">
								<view class="fe-biz-card__header">📋 订单 #2024-002 · 促销推广</view>
								<view class="fe-biz-card__row"><text>状态</text><text class="fe-biz-card__val" style="color:#F59E0B;">待确认</text></view>
								<view class="fe-biz-card__row"><text>人数/时间</text><text class="fe-biz-card__val">5人 · 01-25至26</text></view>
							</view>
						</view>
					</view>

					<!-- Summary bubbles -->
					<view v-else-if="msg.type === 'summary1'" class="fe-summary-bubble" @tap="openSheet('draft')" :id="'msg-' + idx">
						<text class="fe-summary-bubble__check">✓</text>
						<text><text class="fe-summary-bubble__text">方案A已确认</text> · 合规优先 · ¥12,800</text>
					</view>
					<view v-else-if="msg.type === 'summary2'" class="fe-summary-bubble" @tap="openSheet('settlement')" :id="'msg-' + idx">
						<text class="fe-summary-bubble__check">✓</text>
						<text><text class="fe-summary-bubble__text">结算已支付</text> · ¥50,400 · BATCH-001</text>
					</view>

					<!-- Knowledge actions -->
					<view v-else-if="msg.type === 'knowledge_actions'" class="fe-chat-msg fe-chat-msg--ai" :id="'msg-' + idx">
						<view class="fe-chat-avatar fe-chat-avatar--ai">AI</view>
						<view class="fe-chat-bubble">
							<view class="fe-quick-actions">
								<view class="fe-quick-action" @tap="triggerAI('政策法规')">
									<view class="fe-quick-action__icon" style="background:#DBEAFE;">📜</view>
									<text class="fe-quick-action__label">政策法规</text>
								</view>
								<view class="fe-quick-action" @tap="triggerAI('税务处理')">
									<view class="fe-quick-action__icon" style="background:#FEF3C7;">💰</view>
									<text class="fe-quick-action__label">税务处理</text>
								</view>
								<view class="fe-quick-action" @tap="triggerAI('合同管理')">
									<view class="fe-quick-action__icon" style="background:#D1FAE5;">📄</view>
									<text class="fe-quick-action__label">合同管理</text>
								</view>
								<view class="fe-quick-action" @tap="triggerAI('社保保险')">
									<view class="fe-quick-action__icon" style="background:#FEE2E2;">🛡</view>
									<text class="fe-quick-action__label">社保保险</text>
								</view>
							</view>
						</view>
					</view>
				</view>
				<view id="chat-bottom-anchor" class="chat-bottom-anchor" />
				</block>
				</block>
			</view>
		</scroll-view>

		<FeReportFloat :visible="showReportFloat" @open="openReportSheet" />

		<!-- Footer: Quick Actions + Input -->
		<view class="chat-footer">
			<view class="fe-quick-actions fe-quick-actions--dock guide-target guide-target--quick-bar">
				<view class="fe-quick-action" @tap="triggerAI('发布需求')">
					<view class="fe-quick-action__icon" style="background:#FEF3C7;">➕</view>
					<text class="fe-quick-action__label">发布需求</text>
				</view>
				<view class="fe-quick-action" @tap="openSheet('cost')">
					<view class="fe-quick-action__icon" style="background:#D1FAE5;">💰</view>
					<text class="fe-quick-action__label">成本测算</text>
				</view>
				<view class="fe-quick-action" @tap="openSheet('progress')">
					<view class="fe-quick-action__icon" style="background:#DBEAFE;">📈</view>
					<text class="fe-quick-action__label">进度总览</text>
				</view>
				<view class="fe-quick-action" @tap="openSheet('settlement')">
					<view class="fe-quick-action__icon" style="background:#FEE2E2;">💳</view>
					<text class="fe-quick-action__label">历史订单</text>
				</view>
			</view>
			<view
				class="fe-input-bar fe-input-bar--embedded"
				:class="{ 'fe-input-bar--disabled': inputDisabled }"
			>
				<view
					class="fe-input-bar__btn fe-input-bar__btn--voice"
					@tap="onVoiceTap"
				>🎤</view>
				<input
					class="fe-input-bar__field"
					v-model="inputText"
					:disabled="inputDisabled"
					:placeholder="inputPlaceholder"
					confirm-type="send"
					@input="onInput"
					@confirm="sendMsg"
				/>
				<view
					class="fe-input-bar__btn fe-input-bar__btn--send"
					:class="{ active: canSend }"
					@tap="sendMsg"
				>➤</view>
			</view>
		</view>

		<!-- Overlay -->
		<view class="fe-overlay" :class="{ 'fe-overlay--active': overlayActive, 'fe-overlay--elevated': sheetElevated }" @tap="closeAll" />

		<!-- Sheets -->
		<FeDraftSheet
			:active="activeSheet === 'draft'"
			:draft="activeDraft"
			@confirm="confirmPlan"
			@updated="onDraftUpdated"
			@view-qr="openDraftQr"
		/>
		<FeCostSheet :active="activeSheet === 'cost'" @confirm="confirmPlan" />
		<FeReportSheet :active="activeSheet === 'report'" @progress="openSheet('progress')" />
		<FeProgressSheet :active="activeSheet === 'progress'" :elevated="sheetElevated" />
		<FeSettlementSheet :active="activeSheet === 'settlement'" @pay="showPayment" />

		<!-- Drawer: Message -->
		<view class="fe-side-drawer" :class="{ 'fe-side-drawer--active': activeDrawer === 'message' }">
			<view class="fe-drawer-header"><view class="fe-drawer-title">🔔 消息与待办</view></view>
			<scroll-view scroll-y class="fe-drawer-body" :show-scrollbar="false">
				<view class="fe-drawer-body__inner">
				<view v-for="(m, i) in inbox" :key="i" class="fe-msg-item">
					<view style="display:flex;justify-content:space-between;margin-bottom:8rpx;">
						<text class="fe-msg-type" :class="'fe-msg-type--' + m.type">{{ m.type === 'pending' ? '待办' : '异常' }}</text>
						<text style="font-size:22rpx;color:#94A3B8;">{{ m.time }}</text>
					</view>
					<view style="font-weight:600;font-size:28rpx;">{{ m.title }}</view>
					<view style="font-size:26rpx;color:#64748B;margin-top:4rpx;">{{ m.desc }}</view>
				</view>
				</view>
			</scroll-view>
		</view>

		<!-- Drawer: 企业管理中枢 -->
		<view class="fe-side-drawer" :class="{ 'fe-side-drawer--active': activeDrawer === 'profile' }">
			<view class="fe-drawer-header"><view class="fe-drawer-title">企业管理中枢</view></view>
			<scroll-view scroll-y class="fe-drawer-body" :show-scrollbar="false">
				<view class="fe-drawer-body__inner">
				<EnterpriseHubPanel ref="hubPanel" show-logout @logout="logout" />
				</view>
			</scroll-view>
		</view>

		<!-- Modal Confirm -->
		<view class="fe-modal-overlay" :class="{ 'fe-modal-overlay--active': modal === 'confirm' || modal === 'payment' || modal === 'paySuccess' }" @tap="closeModal" />
		<view class="fe-modal" :class="{ 'fe-modal--active': modal === 'confirm' }">
			<view class="fe-modal-body">
				<view class="fe-modal-icon fe-modal-icon--success">✓</view>
				<view class="fe-modal-title">{{ confirmModalTitle }}</view>
				<view class="fe-modal-desc">
					<view>{{ confirmModalDescMain }}</view>
					<view>{{ confirmModalDescSub }}</view>
				</view>
			</view>
			<view class="fe-modal-footer">
				<view class="fe-modal-btn fe-modal-btn--cancel" @tap="closeModal">稍后查看</view>
				<view class="fe-modal-btn fe-modal-btn--confirm" @tap="showQR">查看二维码</view>
			</view>
		</view>

		<FeBatchQrModal :active="modal === 'qr'" :batch="qrBatch" @close="closeModal" @progress="openQrProgress" />

		<!-- Modal Payment -->
		<view class="fe-modal" :class="{ 'fe-modal--active': modal === 'payment' }">
			<view class="fe-modal-body">
				<view class="fe-modal-title">确认支付 ¥52,800</view>
				<view class="fe-modal-desc">将从企业对公账户扣款\n浦东仓库搬运 BATCH-001</view>
			</view>
			<view class="fe-modal-footer">
				<view class="fe-modal-btn fe-modal-btn--cancel" @tap="closeModal">取消</view>
				<view class="fe-modal-btn fe-modal-btn--confirm" @tap="showPaySuccess">确认支付</view>
			</view>
		</view>

		<!-- Modal Pay Success -->
		<view class="fe-modal" :class="{ 'fe-modal--active': modal === 'paySuccess' }">
			<view class="fe-modal-body">
				<view class="fe-modal-icon fe-modal-icon--success">✓</view>
				<view class="fe-modal-title">支付成功</view>
				<view class="fe-modal-desc">¥52,800 已支付\n结算单 BATCH-001</view>
			</view>
			<view class="fe-modal-footer">
				<view class="fe-modal-btn fe-modal-btn--confirm" style="flex:1;" @tap="closeModal">完成</view>
			</view>
		</view>
	</view>
</template>

<script>
import EnterpriseHubPanel from '@/packageA/components/EnterpriseHubPanel.vue'
import FeDraftSheet from '@/packageA/components/chat/FeDraftSheet.vue'
import FeCostSheet from '@/packageA/components/chat/FeCostSheet.vue'
import FeProgressSheet from '@/packageA/components/chat/FeProgressSheet.vue'
import FeSettlementSheet from '@/packageA/components/chat/FeSettlementSheet.vue'
import FeReportSheet from '@/packageA/components/chat/FeReportSheet.vue'
import FeReportFloat from '@/packageA/components/chat/FeReportFloat.vue'
import FeBatchQrModal from '@/packageA/components/chat/FeBatchQrModal.vue'
import store from '@/common/store.js'
import { MESSAGES, BATCH_QR, showToast } from '@/common/chat-data.js'
import { listConversations, createConversation, streamConversationChat, listConversationMessages } from '@/api/conversation.js'
import { getDraftDetail } from '@/api/draft.js'
import {
	getNewChatGreeting,
	mapConversationItem,
	mapConversationMessage,
	calcLastMessagePage,
	CONVERSATION_MESSAGE_PAGE_SIZE
} from '@/utils/conversation.js'
import {
	shouldFetchDraftCard,
	buildDraftCardMessage,
	mapDraftDetailToCard,
	getDraftStatus
} from '@/utils/draft.js'
import {
	buildJobOfferFromDraft,
	saveJobOffer,
	buildJobOfferPageUrl,
	buildJobOfferShareMessage
} from '@/utils/job-offer.js'

export default {
	name: 'EnterpriseHome',
	options: {
		styleIsolation: 'shared'
	},
	props: {
		active: { type: Boolean, default: true }
	},
	components: {
		EnterpriseHubPanel,
		FeDraftSheet,
		FeCostSheet,
		FeProgressSheet,
		FeSettlementSheet,
		FeReportSheet,
		FeReportFloat,
		FeBatchQrModal
	},
	data() {
		return {
			user: {},
			enterprise: {},
			sessions: [],
			sessionsLoading: false,
			creatingSession: false,
			currentSession: '',
			currentConversationId: null,
			messages: [],
			messagesLoading: false,
			messagesLoadingMore: false,
			historyPage: 1,
			hasMoreHistory: false,
			hasMessageHistory: false,
			messagePageSize: CONVERSATION_MESSAGE_PAGE_SIZE,
			inputText: '',
			canSend: false,
			chatStreaming: false,
			abortChat: null,
			scrollTop: 0,
			scrollIntoView: '',
			scrollWithAnimation: true,
			stickToBottom: true,
			sidebarOpen: false,
			activeSheet: '',
			activeDraft: null,
			activeDrawer: '',
			modal: '',
			confirmInfo: null,
			qrBatch: { ...BATCH_QR },
			inbox: MESSAGES,
			reportCardVisible: true,
			reportObserver: null,
			_localMsgSeq: 0
		}
	},
	computed: {
		overlayActive() {
			return !!(this.sidebarOpen || this.activeSheet || this.activeDrawer)
		},
		confirmModalTitle() {
			const info = this.confirmInfo
			if (!info || !info.title) return '方案已确认'
			return `已确认：${info.title}`
		},
		confirmModalDescMain() {
			const info = this.confirmInfo
			if (!info) return '方案确认成功'
			const parts = []
			if (info.tagsText) parts.push(info.tagsText)
			if (info.total) parts.push(`总支出 ${info.total}`)
			if (info.avgCost) parts.push(`人均 ${info.avgCost}`)
			return parts.length ? parts.join(' · ') : '方案确认成功'
		},
		confirmModalDescSub() {
			const info = this.confirmInfo
			const orderId = info && info.orderId
			if (orderId) return `订单 ${orderId} 已生成，可查看批次二维码`
			return '确认后可查看并分享批次二维码'
		},
		hasReportMessage() {
			return this.messages.some((m) => m.type === 'report')
		},
		showReportFloat() {
			return this.hasReportMessage && !this.reportCardVisible
		},
		showNewChatEmpty() {
			return !this.sessionsLoading && !this.currentSession && !this.sessions.length
		},
		/** 未开启/选中会话时禁止输入 */
		inputDisabled() {
			return !this.currentConversationId || this.chatStreaming
		},
		inputPlaceholder() {
			if (!this.currentConversationId) return '请先开启新对话'
			if (this.chatStreaming) return 'AI 正在回复...'
			return '输入需求或按住说话...'
		},
		newChatGreeting() {
			return getNewChatGreeting()
		},
		sheetElevated() {
			return this.modal === 'qr' && this.activeSheet === 'progress'
		}
	},
	onShow() {
		if (!this.active) return
		this.initHome()
	},
	mounted() {
		if (this.active) this.initHome()
	},
	watch: {
		active(val) {
			if (val) this.initHome()
		}
	},
	onReady() {
		this.setupReportObserver()
	},
	beforeDestroy() {
		this.disconnectReportObserver()
		this.stopChatStream()
		if (this._scrollTimer) clearTimeout(this._scrollTimer)
	},
	methods: {
		toast: showToast,
		async initHome() {
			const s = store.getState()
			this.user = s.user
			this.enterprise = s.enterprise
			await this.fetchSessions({ autoLoad: true })
		},
		async fetchSessions(options = {}) {
			const { autoLoad = false, showError = false } = options
			this.sessionsLoading = true
			try {
				const list = await listConversations({ status: 'active' }, { showError })
				this.sessions = (list || []).map(mapConversationItem)
				if (autoLoad) {
					if (this.sessions.length) {
						const current = this.sessions.find((item) => item.conversationNo === this.currentSession)
						const target = current || this.sessions[0]
						await this.loadSession(target.conversationNo, target.chatType)
					} else if (!this.currentSession) {
						this.messages = []
					}
				}
			} catch (e) {
				if (autoLoad && !this.currentSession) {
					this.messages = []
				}
			} finally {
				this.sessionsLoading = false
			}
		},
		buildWelcomeMessages() {
			return [{
				type: 'text',
				role: 'ai',
				content: getNewChatGreeting(),
				msgKey: this.nextLocalMsgKey()
			}]
		},
		nextLocalMsgKey() {
			this._localMsgSeq += 1
			return -this._localMsgSeq
		},
		resetMessagePagination() {
			this.historyPage = 1
			this.hasMoreHistory = false
			this.hasMessageHistory = false
			this.messagesLoading = false
			this.messagesLoadingMore = false
		},
		async loadSession(conversationNo, chatType) {
			this.abortChatStream()
			this.currentSession = conversationNo
			const session = this.sessions.find((item) => item.conversationNo === conversationNo)
			this.currentConversationId = session ? session.id : null
			this.resetMessagePagination()
			this.messages = []
			this.reportCardVisible = true
			await this.fetchLatestMessages({ scrollBottom: true })
			this.$nextTick(() => {
				this.setupReportObserver()
				setTimeout(() => this.checkReportVisibility(), 120)
			})
		},
		async fetchLatestMessages(options = {}) {
			const { scrollBottom = false } = options
			if (!this.currentConversationId) {
				this.messages = this.buildWelcomeMessages()
				return
			}

			this.messagesLoading = true
			try {
				const probe = await listConversationMessages(
					this.currentConversationId,
					{ page: 1, size: this.messagePageSize },
					{ showError: true }
				)
				const total = probe.total || 0
				if (!total) {
					this.messages = this.buildWelcomeMessages()
					this.hasMoreHistory = false
					this.hasMessageHistory = false
					return
				}

				const lastPage = calcLastMessagePage(total, this.messagePageSize)
				let pageData = probe
				if (lastPage > 1) {
					pageData = await listConversationMessages(
						this.currentConversationId,
						{ page: lastPage, size: this.messagePageSize },
						{ showError: true }
					)
				}

				this.historyPage = lastPage
				this.hasMoreHistory = lastPage > 1
				this.hasMessageHistory = true
				this.messages = (pageData.items || []).map(mapConversationMessage)
				await this.hydrateDraftCardsFromMessages()
				if (scrollBottom) {
					this.stickToBottom = true
					this.ensureChatBottom()
				}
			} catch (e) {
				this.messages = this.buildWelcomeMessages()
				this.hasMoreHistory = false
				this.hasMessageHistory = false
			} finally {
				this.messagesLoading = false
			}
		},
		measureChatContentHeight() {
			return new Promise((resolve) => {
				const query = uni.createSelectorQuery().in(this)
				query.select('.chat-area__inner').boundingClientRect()
				query.exec((res) => {
					resolve((res[0] && res[0].height) || 0)
				})
			})
		},
		restoreScrollAfterPrepend(beforeHeight, beforeTop) {
			return new Promise((resolve) => {
				this.$nextTick(() => {
					setTimeout(async () => {
						const afterHeight = await this.measureChatContentHeight()
						const delta = afterHeight - beforeHeight
						this._programmaticScroll = true
						this.scrollWithAnimation = false
						this._scrollBump = (this._scrollBump || 0) + 1
						this.scrollTop = Math.max(0, beforeTop + delta) + this._scrollBump
						setTimeout(() => {
							this._programmaticScroll = false
							resolve()
						}, 60)
					}, 50)
				})
			})
		},
		async loadMoreHistory() {
			if (
				!this.hasMoreHistory ||
				this.messagesLoadingMore ||
				this.messagesLoading ||
				this.chatStreaming ||
				!this.currentConversationId
			) {
				return
			}

			const olderPage = this.historyPage - 1
			if (olderPage < 1) {
				this.hasMoreHistory = false
				return
			}

			this.messagesLoadingMore = true
			try {
				const beforeHeight = await this.measureChatContentHeight()
				const beforeTop = this._lastScrollTop || 0
				const pageData = await listConversationMessages(
					this.currentConversationId,
					{ page: olderPage, size: this.messagePageSize },
					{ showError: false }
				)
				const older = (pageData.items || []).map(mapConversationMessage)
				if (!older.length) {
					this.hasMoreHistory = false
					return
				}

				this.messages = [...older, ...this.messages]
				this.historyPage = olderPage
				this.hasMoreHistory = olderPage > 1
				await this.hydrateDraftCardsFromMessages(older)
				await this.restoreScrollAfterPrepend(beforeHeight, beforeTop)
			} catch (e) {
				// 错误提示由 request.js 统一处理
			} finally {
				this.messagesLoadingMore = false
			}
		},
		onChatScrollToUpper() {
			this.loadMoreHistory()
		},
		switchSession(conversationNo) {
			if (this.currentSession === conversationNo) {
				this.sidebarOpen = false
				return
			}
			this.sidebarOpen = false
			const session = this.sessions.find((item) => item.conversationNo === conversationNo)
			this.loadSession(conversationNo, session && session.chatType)
		},
		switchSessionByIndex(index) {
			const session = this.sessions[index]
			if (!session) return
			this.switchSession(session.conversationNo)
		},
		async newChat() {
			if (this.creatingSession) return
			this.creatingSession = true
			this.sidebarOpen = false
			try {
				const created = await createConversation({
					chatType: 'employment',
					title: '新对话'
				})
				const item = mapConversationItem(created)
				this.sessions = [
					item,
					...this.sessions.filter((session) => session.conversationNo !== item.conversationNo)
				]
				this.loadSession(item.conversationNo, item.chatType)
				this.toast('已开启新对话')
			} catch (e) {
				// 错误提示由 request.js 统一处理
			} finally {
				this.creatingSession = false
			}
		},
		scrollBottom(animated = true, force = false) {
			if (!force && !this.stickToBottom && !this.chatStreaming) return
			if (this._scrollTimer) clearTimeout(this._scrollTimer)
			this._scrollTimer = setTimeout(() => {
				this._scrollTimer = null
				this.scrollWithAnimation = !!animated
				this._programmaticScroll = true
				this._scrollBump = (this._scrollBump || 0) + 1
				this.scrollTop = 100000 + this._scrollBump
				setTimeout(() => {
					this._programmaticScroll = false
				}, animated ? 300 : 60)
				setTimeout(() => this.checkReportVisibility(), 120)
			}, animated ? 40 : 0)
		},
		scrollToBottomAnchor() {
			this.scrollIntoView = ''
			this.$nextTick(() => {
				this.scrollIntoView = 'chat-bottom-anchor'
			})
		},
		ensureChatBottom() {
			this.stickToBottom = true
			const scroll = () => {
				this.scrollBottom(false, true)
				this.scrollToBottomAnchor()
			}
			this.$nextTick(() => {
				scroll()
				setTimeout(scroll, 60)
				setTimeout(scroll, 180)
				setTimeout(scroll, 360)
			})
		},
		onChatScroll(e) {
			const detail = e.detail || {}
			this._lastScrollTop = detail.scrollTop || 0
			if (this._programmaticScroll) {
				this.checkReportVisibility()
				return
			}
			const gap = (detail.scrollHeight || 0) - (detail.scrollTop || 0) - (detail.clientHeight || 0)
			if (this.chatStreaming) {
				// 流式输出时内容可能突增，仅当明显上滑才取消贴底
				if (gap > 280) this.stickToBottom = false
			} else {
				this.stickToBottom = gap < 120
			}
			if (
				!this.chatStreaming &&
				!this.messagesLoading &&
				!this.messagesLoadingMore &&
				this._lastScrollTop <= 20
			) {
				this.loadMoreHistory()
			}
			this.checkReportVisibility()
		},
		setupReportObserver() {
			this.disconnectReportObserver()
			if (!this.hasReportMessage) return
			this.$nextTick(() => {
				this.reportObserver = uni.createIntersectionObserver(this, { thresholds: [0, 0.01, 1] })
				this.reportObserver
					.relativeTo('.chat-area', { top: 0, bottom: 0 })
					.observe('.report-card-anchor', (res) => {
						this.reportCardVisible = res.intersectionRatio > 0
					})
			})
		},
		disconnectReportObserver() {
			if (this.reportObserver) {
				this.reportObserver.disconnect()
				this.reportObserver = null
			}
		},
		checkReportVisibility() {
			if (!this.hasReportMessage) {
				this.reportCardVisible = true
				return
			}
			const query = uni.createSelectorQuery().in(this)
			query.select('.chat-area').boundingClientRect()
			query.select('.report-card-anchor').boundingClientRect()
			query.exec((res) => {
				const area = res[0]
				const card = res[1]
				if (!area || !card) return
				this.reportCardVisible = card.bottom > area.top && card.top < area.bottom
			})
		},
		openReportSheet() {
			this.openSheet('report')
		},
		onInput() {
			this.canSend =
				!this.inputDisabled &&
				!!this.currentConversationId &&
				this.inputText.trim().length > 0 &&
				!this.chatStreaming
		},
		onVoiceTap() {
			if (this.inputDisabled) {
				if (!this.currentConversationId) this.toast('请先开启新对话')
				return
			}
			this.toast('按住说话...')
		},
		stopChatStream() {
			if (this.abortChat) {
				this.abortChat()
				this.abortChat = null
			}
			this.chatStreaming = false
		},
		abortChatStream() {
			if (this.abortChat) {
				this.abortChat()
				this.abortChat = null
			}
		},
		sendMsg() {
			if (this.inputDisabled && !this.chatStreaming) {
				if (!this.currentConversationId) this.toast('请先开启新对话')
				return
			}
			const text = this.inputText.trim()
			if (!text || this.chatStreaming) return
			if (!this.currentConversationId) {
				this.toast('请先开启新对话')
				return
			}

			this.abortChatStream()
			this.stickToBottom = true
			this.messages.push({ type: 'text', role: 'user', content: text, msgKey: this.nextLocalMsgKey() })
			const aiIdx = this.messages.length
			this.messages.push({
				type: 'text',
				role: 'ai',
				content: '',
				streaming: true,
				msgKey: this.nextLocalMsgKey()
			})
			this.inputText = ''
			this.canSend = false
			this.chatStreaming = true
			this.scrollBottom()

			this.abortChat = streamConversationChat({
				conversationId: this.currentConversationId,
				message: text,
				onDelta: (assembledText) => {
					const prev = this.messages[aiIdx].content || ''
					this.$set(this.messages[aiIdx], 'content', assembledText || '')
					const force = !!(assembledText && assembledText.length - prev.length > 80)
					this.scrollBottom(false, force)
					if (force) {
						this.$nextTick(() => this.scrollBottom(false, true))
					}
				},
				onDone: async (assembledText, cardMeta) => {
					this.$set(this.messages[aiIdx], 'streaming', false)
					if (assembledText) {
						this.$set(this.messages[aiIdx], 'content', assembledText)
					} else if (!this.messages[aiIdx].content) {
						this.$set(this.messages[aiIdx], 'content', '暂无回复，请稍后重试')
					}
					if (shouldFetchDraftCard(cardMeta)) {
						await this.appendDraftCardById(cardMeta.relatedDraftId)
					}
					this.ensureChatBottom()
					this.stopChatStream()
					this.fetchSessions({ showError: false })
				},
				onError: (err) => {
					this.$set(this.messages[aiIdx], 'streaming', false)
					const message = (err && err.message) || '对话失败，请稍后重试'
					if (!this.messages[aiIdx].content) {
						this.$set(this.messages[aiIdx], 'content', message)
					} else {
						this.toast(message)
					}
					this.ensureChatBottom()
					this.stopChatStream()
				}
			})
		},
		triggerAI(text) {
			if (!this.currentConversationId) {
				this.toast('请先开启新对话')
				return
			}
			if (this.chatStreaming) return
			this.inputText = text
			this.canSend = true
			this.sendMsg()
		},
		isDraftConfirmedByIndex(idx) {
			const msg = this.messages[idx]
			return !!(msg && msg.draft && getDraftStatus(msg.draft) === 'confirmed')
		},
		draftCardStatusLabelByIndex(idx) {
			return this.isDraftConfirmedByIndex(idx) ? '已确认' : '未确认'
		},
		async openDraftByIndex(idx) {
			const msg = this.messages[idx]
			if (!msg || msg.type !== 'draft' || !msg.draft) return
			let draft = msg.draft
			this.closeAll()
			this.activeDraft = draft
			setTimeout(() => { this.activeSheet = 'draft' }, 50)

			// 回源刷新状态（确认后缺省字段仍能正确展示）
			const draftId = draft.draftId
			if (draftId == null) return
			try {
				const detail = await getDraftDetail(draftId, { showError: false })
				if (!detail || detail.id == null) return
				const card = mapDraftDetailToCard(detail)
				// 保留本地已确认方案快照，避免刷新后丢失成本展示
				if (draft.costPlans) card.costPlans = draft.costPlans
				if (draft.confirmedPlan) card.confirmedPlan = draft.confirmedPlan
				if (draft.confirmedPlanTitle) card.confirmedPlanTitle = draft.confirmedPlanTitle
				if (draft.orderId && !card.orderId) card.orderId = draft.orderId
				if (draft.qrCodeUrl && !card.qrCodeUrl) card.qrCodeUrl = draft.qrCodeUrl
				if (draft.selectedSchemeCode && !card.selectedSchemeCode) {
					card.selectedSchemeCode = draft.selectedSchemeCode
				}
				this.onDraftUpdated(card)
			} catch (e) {
				// 静默失败，沿用本地草稿
			}
		},
		onDraftUpdated(draftCard) {
			if (!draftCard || draftCard.draftId == null) return
			this.activeDraft = draftCard
			for (let i = 0; i < this.messages.length; i++) {
				const msg = this.messages[i]
				if (msg.type === 'draft' && msg.draftId === draftCard.draftId) {
					this.$set(this.messages[i], 'draft', draftCard)
					break
				}
			}
		},
		/**
		 * 历史消息中 content_type=card_draft 且带 related_draft_id 时，拉详情并插入草稿卡片
		 * @param {Array} [sourceMessages] 仅处理给定列表，默认扫描当前全部消息
		 */
		async hydrateDraftCardsFromMessages(sourceMessages) {
			const list = Array.isArray(sourceMessages) ? sourceMessages : this.messages
			const draftIds = []
			for (let i = 0; i < list.length; i++) {
				const msg = list[i]
				if (!msg || msg.type !== 'text') continue
				if (msg.contentType !== 'card_draft' || msg.relatedDraftId == null) continue
				if (this.messages.some((m) => m.type === 'draft' && m.draftId === msg.relatedDraftId)) continue
				if (draftIds.indexOf(msg.relatedDraftId) === -1) {
					draftIds.push(msg.relatedDraftId)
				}
			}
			for (let i = 0; i < draftIds.length; i++) {
				await this.appendDraftCardById(draftIds[i], { afterRelatedText: true })
			}
		},
		/**
		 * 查询草稿详情并插入聊天气泡卡片
		 * @param {number} draftId
		 * @param {{ afterRelatedText?: boolean }} [options]
		 */
		async appendDraftCardById(draftId, options = {}) {
			if (draftId == null) return null
			const id = Number(draftId)
			if (Number.isNaN(id)) return null
			if (this.messages.some((m) => m.type === 'draft' && m.draftId === id)) return null

			try {
				const detail = await getDraftDetail(id, { showError: false })
				if (!detail || detail.id == null) return null
				const cardMsg = buildDraftCardMessage(detail, this.nextLocalMsgKey())

				if (options.afterRelatedText) {
					let insertAt = -1
					for (let i = this.messages.length - 1; i >= 0; i--) {
						const msg = this.messages[i]
						if (msg.type === 'text' && msg.relatedDraftId === id) {
							insertAt = i + 1
							break
						}
					}
					if (insertAt >= 0) {
						this.messages.splice(insertAt, 0, cardMsg)
					} else {
						this.messages.push(cardMsg)
					}
				} else {
					this.messages.push(cardMsg)
				}
				this.ensureChatBottom()
				return cardMsg
			} catch (e) {
				return null
			}
		},
		openSidebar() {
			if (this.sidebarOpen) {
				this.sidebarOpen = false
				return
			}
			this.activeSheet = ''
			this.activeDrawer = ''
			this.sidebarOpen = true
			this.fetchSessions()
		},
		openSheet(name) {
			this.closeAll()
			setTimeout(() => { this.activeSheet = name }, 50)
		},
		openDrawer(name) {
			this.closeAll()
			setTimeout(() => {
				this.activeDrawer = name
				if (name === 'profile' && this.$refs.hubPanel) {
					this.$refs.hubPanel.refreshPasswordStatus()
				}
			}, 50)
		},
		closeAll() {
			this.sidebarOpen = false
			this.activeSheet = ''
			this.activeDrawer = ''
			this.activeDraft = null
		},
		closeModal() {
			this.modal = ''
			this.confirmInfo = null
		},
		/**
		 * 用工场景标题：地点+岗位 / 草稿标题
		 */
		resolveDraftSceneTitle(draft, fallback) {
			if (!draft) return fallback || '用工批次'
			const title = draft.title && draft.title !== '用工草稿' ? draft.title : ''
			if (title) return title
			const loc = draft.workLocation && draft.workLocation !== '待补充' ? draft.workLocation : ''
			const type = draft.workType && draft.workType !== '待补充' ? draft.workType : ''
			const combined = `${loc}${type}`
			return combined || fallback || '用工批次'
		},
		buildQrBatch(draft, options = {}) {
			const draftId = options.draftId
				|| (draft && (draft.draftId != null ? draft.draftId : (draft.detail && draft.detail.id)))
				|| null
			const batchId = (draft && draft.draftNo) || (draftId != null ? `draft_${draftId}` : '')
			const sceneTitle = this.resolveDraftSceneTitle(draft, options.schemeTitle)
			const workerCount = draft && draft.workerCount != null ? Number(draft.workerCount) : 0
			const subtitle = batchId ? `${sceneTitle} ${batchId}` : sceneTitle
			const enterpriseName = (this.enterprise && this.enterprise.name) || ''
			const scheme = options.scheme || (draft && draft.confirmedPlan) || null
			const qrCodeUrl = options.qrCodeUrl
				|| (draft && (draft.qrCodeUrl || draft.qr_code_url || draft.ar_code_url))
				|| ''
			const offer = buildJobOfferFromDraft(draft, {
				batchId,
				draftId,
				scheme,
				schemeTitle: options.schemeTitle || (scheme && scheme.title),
				enterpriseName
			})
			saveJobOffer(offer)
			return Object.assign({}, BATCH_QR, {
				modalTitle: '方案已确认',
				title: sceneTitle,
				batchId,
				draftId: offer.draftId,
				subtitle,
				qrCodeUrl,
				total: workerCount > 0 ? workerCount : BATCH_QR.total,
				registered: 0,
				hint: '分享给临时工扫码即可登记',
				shareLink: buildJobOfferPageUrl(offer)
			})
		},
		pickConfirmQrUrl(result) {
			if (!result || typeof result !== 'object') return ''
			return result.qrCodeUrl
				|| result.qr_code_url
				|| result.ar_code_url
				|| result.arCodeUrl
				|| ''
		},
		confirmPlan(payload) {
			const scheme = (payload && payload.scheme) || null
			const result = (payload && payload.result) || {}
			const draft = this.activeDraft
			const orderId = result.orderId || result.order_id || ''
			const qrCodeUrl = this.pickConfirmQrUrl(result)
			const tags = (scheme && Array.isArray(scheme.compliance) ? scheme.compliance : [])
				.filter(Boolean)
			this.confirmInfo = {
				title: (scheme && scheme.title) || (payload && payload.schemeCode) || '',
				code: (payload && payload.schemeCode) || (scheme && scheme.code) || '',
				total: (scheme && scheme.total) || '',
				avgCost: (scheme && scheme.avgCost) || '',
				tagsText: tags.join('、'),
				orderId,
				qrCodeUrl
			}
			this.qrBatch = this.buildQrBatch(draft, {
				scheme,
				schemeTitle: scheme && scheme.title,
				qrCodeUrl
			})
			// 回写状态到气泡草稿，便于再次分享 / 查看二维码
			if (draft && draft.draftId != null) {
				this.onDraftUpdated(Object.assign({}, draft, {
					orderId,
					qrCodeUrl,
					status: 'confirmed',
					confirmedPlan: (scheme && {
						id: scheme.id || scheme.code,
						code: scheme.code,
						title: scheme.title,
						total: scheme.total,
						avgCost: scheme.avgCost,
						rows: scheme.rows,
						breakdown: scheme.breakdown,
						compliance: scheme.compliance,
						raw: scheme.raw
					}) || draft.confirmedPlan
				}))
			}
			this.closeAll()
			setTimeout(() => { this.modal = 'confirm' }, 400)
		},
		showQR() {
			if (!this.qrBatch || !this.qrBatch.subtitle) {
				this.qrBatch = this.buildQrBatch(null, {
					schemeTitle: this.confirmInfo && this.confirmInfo.title,
					qrCodeUrl: this.confirmInfo && this.confirmInfo.qrCodeUrl
				})
			} else if (this.confirmInfo && this.confirmInfo.qrCodeUrl && !this.qrBatch.qrCodeUrl) {
				this.$set(this.qrBatch, 'qrCodeUrl', this.confirmInfo.qrCodeUrl)
			}
			this.modal = 'qr'
		},
		openDraftQr() {
			this.qrBatch = this.buildQrBatch(this.activeDraft, {
				scheme: this.activeDraft && this.activeDraft.confirmedPlan,
				schemeTitle: this.activeDraft && this.activeDraft.confirmedPlanTitle,
				qrCodeUrl: this.activeDraft && (this.activeDraft.qrCodeUrl || this.activeDraft.qr_code_url)
			})
			this.modal = 'qr'
		},
		/**
		 * 供首页 onShareAppMessage 读取
		 */
		getShareAppMessage() {
			const draftId = (this.qrBatch && this.qrBatch.draftId) || ''
			return buildJobOfferShareMessage({ draftId })
		},
		openQrProgress() {
			this.openSheet('progress')
		},
		showPayment() {
			this.closeAll()
			setTimeout(() => { this.modal = 'payment' }, 300)
		},
		showPaySuccess() {
			this.modal = 'paySuccess'
		},
		logout() {
			store.logout()
			uni.reLaunch({ url: '/packageA/auth/login' })
		}
	}
}
</script>

<style lang="scss" scoped>
.chat-page {
	height: 100%;
	overflow: hidden;
	background: $fe-bg;
}

.chat-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 99;
	background: #ffffff;
	border-bottom: 1rpx solid $fe-border-light;
	box-sizing: border-box;
}

.chat-header__row {
	height: $fe-h-page-bar;
	display: flex;
	flex-direction: row;
	align-items: center;
	flex-wrap: nowrap;
	padding: 0 24rpx;
	box-sizing: border-box;
}

.chat-header__title {
	flex: 1;
	min-width: 0;
	margin: 0 12rpx;
	font-weight: 700;
	font-size: 34rpx;
	color: $fe-foreground;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	line-height: $fe-h-page-bar;
}

.chat-header__actions {
	display: flex;
	flex-direction: row;
	align-items: center;
	flex-wrap: nowrap;
	flex-shrink: 0;
	gap: 4rpx;
}

.fe-nav-icon {
	font-size: 36rpx;
	line-height: 1;
	color: $fe-gray-500;
}

.fe-nav-icon--plus {
	font-size: 44rpx;
	font-weight: 300;
	color: $fe-gray-600;
}

.chat-area {
	position: fixed;
	top: $fe-h-page-bar;
	left: 0;
	right: 0;
	bottom: calc(#{$fe-h-input-bar} + #{$fe-h-quick-bar} + #{$fe-h-safe-bottom});
	box-sizing: border-box;
}

.chat-footer {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 99;
	background: rgba(255, 255, 255, 0.92);
	border-top: 1rpx solid $fe-border-light;
	padding-bottom: $fe-h-safe-bottom;
	box-sizing: border-box;
}

.fe-input-bar--embedded {
	position: relative;
	left: auto;
	right: auto;
	bottom: auto;
	border-top: 1rpx solid $fe-border-light;
	background: transparent;
	padding-bottom: 20rpx;
}

.fe-input-bar--disabled {
	opacity: 0.55;
}

.fe-input-bar--disabled .fe-input-bar__field {
	background: $fe-gray-100;
	color: $fe-gray-400;
}

.fe-input-bar--disabled .fe-input-bar__btn {
	opacity: 0.7;
}

.chat-area__inner {
	padding: 32rpx;
	padding-bottom: 48rpx;
}

.chat-msg-wrap {
	width: 100%;
}

.chat-status {
	display: flex;
	justify-content: center;
	padding: 24rpx 0 8rpx;
}

.chat-status--top {
	padding: 8rpx 0 24rpx;
}

.chat-status__text {
	font-size: 24rpx;
	color: $fe-gray-500;
}

.chat-status__text--muted {
	color: $fe-gray-400;
}

.chat-bottom-anchor {
	height: 2rpx;
	width: 100%;
}

.sidebar-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 28rpx 28rpx 20rpx;
	border-bottom: 1rpx solid $fe-border-light;
}

.sidebar-head__title {
	font-size: 30rpx;
	font-weight: 700;
}

.sidebar-head__add {
	width: 64rpx;
	height: 64rpx;
	border-radius: $fe-radius-sm;
	background: $fe-primary;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 32rpx;
}

.sidebar-list {
	height: calc(100% - 120rpx);
}

.sidebar-status {
	padding: 48rpx 28rpx;
	text-align: center;
}

.sidebar-status__text {
	font-size: 26rpx;
	color: $fe-gray-500;
}

.sidebar-status--action {
	cursor: pointer;
}

.sidebar-status__text--action {
	color: $fe-primary;
	font-weight: 600;
}

.chat-empty {
	min-height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 80rpx 48rpx;
	text-align: center;
	box-sizing: border-box;
}

.chat-empty__icon {
	width: 120rpx;
	height: 120rpx;
	border-radius: 50%;
	background: $fe-primary-bg;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 56rpx;
	margin-bottom: 32rpx;
}

.chat-empty__title {
	font-size: 36rpx;
	font-weight: 700;
	color: $fe-foreground;
	margin-bottom: 48rpx;
	line-height: 1.5;
	max-width: 520rpx;
}

.chat-empty__btn {
	padding: 24rpx 64rpx;
	border-radius: $fe-radius-full;
	background: $fe-primary;
	color: #fff;
	font-size: 30rpx;
	font-weight: 600;
}

/* H5：避开浏览器/WebView 顶栏与安全区，避免头部被遮住 */
/* #ifdef H5 */
.chat-header {
	padding-top: constant(safe-area-inset-top);
	padding-top: env(safe-area-inset-top);
	z-index: 200;
}

.chat-header__row {
	height: 96rpx;
	padding: 0 32rpx;
}

.chat-header__title {
	font-size: 32rpx;
	line-height: 96rpx;
}

.chat-area {
	top: calc(96rpx + constant(safe-area-inset-top));
	top: calc(96rpx + env(safe-area-inset-top));
}

.fe-sidebar {
	top: calc(96rpx + constant(safe-area-inset-top));
	top: calc(96rpx + env(safe-area-inset-top));
}
/* #endif */
</style>
