<template>
	<business-page-layout title="挂号详情" :show-back="true">
		<view class="page">
			<view v-if="loading" class="empty">加载中...</view>
			<template v-else-if="!detail.id">
				<view class="empty">暂无挂号信息</view>
			</template>
			<template v-else>
				<!-- 有药品/回答时才出 Tab；仅基本信息时不展示 Tab 栏 -->
				<view v-if="visibleTabs.length > 1" class="tabs">
					<view
						v-for="(t, idx) in visibleTabs"
						:key="t.key"
						class="tab"
						:class="{ on: tabIndex === idx }"
						@click="selectTab(idx)"
					>
						<text class="tab-text">{{ t.label }}</text>
						<view v-if="tabIndex === idx" class="tab-bar" />
					</view>
				</view>
				<!-- 多 Tab：固定高度 swiper，避免与外层页面滚动抢手势 -->
				<swiper
					v-if="visibleTabs.length > 1"
					class="tab-swiper"
					:style="{ height: swiperHeightPx + 'px' }"
					:current="tabIndex"
					:duration="200"
					@change="onTabSwiperChange"
				>
					<swiper-item v-for="t in visibleTabs" :key="'sw-' + t.key">
						<scroll-view
							scroll-y
							class="tab-scroll"
							:style="{ height: swiperHeightPx + 'px' }"
						>
							<view v-if="t.key === 'basic'" class="card">
								<view class="row">
									<text class="label">订单号</text>
									<text class="value">{{ detail.order_no || detail.order_number || '—' }}</text>
								</view>
								<view class="row">
									<text class="label">诊所</text>
									<text class="value">{{ detail.store || '—' }}</text>
								</view>
								<view class="row">
									<text class="label">医生</text>
									<text class="value">{{ detail.doctor || '—' }}</text>
								</view>
								<view class="row">
									<text class="label">挂号类型</text>
									<text class="value">{{ detail.type_text || '—' }}</text>
								</view>
								<view class="row">
									<text class="label">状态</text>
									<text class="value accent">{{ detail.status_text || '—' }}</text>
								</view>
								<view class="row">
									<text class="label">金额</text>
									<text class="value">¥{{ formatPrice(detail.price) }}</text>
								</view>
								<view class="row">
									<text class="label">支付</text>
									<text class="value">{{ Number(detail.is_pay) === 1 ? '已支付' : '未支付' }}</text>
								</view>
								<view class="row">
									<text class="label">创建时间</text>
									<text class="value">{{ detail.created_at || '—' }}</text>
								</view>
								<view v-if="detail.pay_time" class="row">
									<text class="label">支付时间</text>
									<text class="value">{{ detail.pay_time }}</text>
								</view>
							</view>
							<view v-else-if="t.key === 'drugs'" class="card">
								<view v-if="!drugRows.length" class="empty-inline">暂无选药</view>
								<view v-for="row in drugRows" :key="row._wxKey" class="drug-row">
									<image
										v-if="row.image"
										class="drug-thumb"
										:src="row.image"
										mode="aspectFill"
										@click="previewDrug(row.image)"
									/>
									<view v-else class="drug-thumb drug-thumb-placeholder">
										<text class="drug-thumb-letter">{{ drugThumbLetter(row.name) }}</text>
									</view>
									<view class="drug-meta">
										<text class="drug-name">{{ row.name || '药品' }}</text>
										<text class="drug-spec">{{ row.specification || '暂无规格' }}</text>
									</view>
									<text class="drug-qty">×{{ row.quantity }}</text>
								</view>
							</view>
							<view v-else-if="t.key === 'answers'" class="card">
								<view v-if="!answerRecords.length" class="empty-inline">暂无回答</view>
								<view v-for="(a, aidx) in answerRecords" :key="'a-' + aidx" class="row answer-row">
									<text class="label">{{ a.question || '问题' }}</text>
									<text class="value">{{ a.answer || '—' }}</text>
								</view>
							</view>
						</scroll-view>
					</swiper-item>
				</swiper>
				<!-- 仅基本信息：无滑动 -->
				<view v-else class="card">
					<view class="row">
						<text class="label">订单号</text>
						<text class="value">{{ detail.order_no || detail.order_number || '—' }}</text>
					</view>
					<view class="row">
						<text class="label">诊所</text>
						<text class="value">{{ detail.store || '—' }}</text>
					</view>
					<view class="row">
						<text class="label">医生</text>
						<text class="value">{{ detail.doctor || '—' }}</text>
					</view>
					<view class="row">
						<text class="label">挂号类型</text>
						<text class="value">{{ detail.type_text || '—' }}</text>
					</view>
					<view class="row">
						<text class="label">状态</text>
						<text class="value accent">{{ detail.status_text || '—' }}</text>
					</view>
					<view class="row">
						<text class="label">金额</text>
						<text class="value">¥{{ formatPrice(detail.price) }}</text>
					</view>
					<view class="row">
						<text class="label">支付</text>
						<text class="value">{{ Number(detail.is_pay) === 1 ? '已支付' : '未支付' }}</text>
					</view>
					<view class="row">
						<text class="label">创建时间</text>
						<text class="value">{{ detail.created_at || '—' }}</text>
					</view>
					<view v-if="detail.pay_time" class="row">
						<text class="label">支付时间</text>
						<text class="value">{{ detail.pay_time }}</text>
					</view>
				</view>
			</template>
		</view>
	</business-page-layout>
</template>

<script>
/**
 * 挂号详情：基本信息 + 条件 Tab（本次选药 / 回答记录）
 * 多 Tab 时用固定高度 swiper 左右滑切换，并在首次进入时短暂提示
 */
import BusinessPageLayout from '@/subPackages/sub_business_shared/components/business-page-layout.vue';
import { getUserPatientRegisterDetail } from '@/api/userPatientProfile.js';

/** 左右滑切换提示只展示一次，避免每次进入打扰 */
const SWIPE_TIP_STORAGE_KEY = 'user_patient_register_detail_swipe_tip';

export default {
	components: { BusinessPageLayout },
	data() {
		return {
			loading: false,
			registerId: 0,
			activeTab: 'basic',
			/** swiper 当前下标，与 activeTab / visibleTabs 同步 */
			tabIndex: 0,
			/** 点击 Tab 与 swiper change 互斥，避免回环 */
			tabSwiperChanging: false,
			/** 按窗口算出的 swiper 像素高度，保证横向滑动可用 */
			swiperHeightPx: 400,
			detail: {},
			registerInfo: null,
			answerRecords: [],
		};
	},
	computed: {
		/** 药品行：多选西药优先，否则单药 */
		drugRows() {
			const info = this.registerInfo;
			if (!info || typeof info !== 'object') return [];
			const arr = info.selected_western_drugs;
			const fallbackQty = info.number != null && info.number !== '' ? Number(info.number) : 1;
			if (Array.isArray(arr) && arr.length) {
				return arr.map((d, idx) => {
					const q = d && d.quantity != null ? Number(d.quantity) : fallbackQty;
					const id = d && (d.drug_id || d.id);
					return {
						_wxKey: 'd-' + (id != null ? id : idx),
						name: (d && d.name) || '',
						specification: (d && (d.specification || d.spec)) || '',
						image: (d && (d.image || d.drug_image)) || '',
						quantity: q >= 1 ? q : 1,
					};
				});
			}
			if (info.drug && info.drug.name) {
				return [{
					_wxKey: 'd-' + (info.drug.drug_id || info.drug.id || 0),
					name: info.drug.name,
					specification: info.drug.specification || info.drug.spec || '',
					image: info.drug.image || info.drug.drug_image || '',
					quantity: fallbackQty >= 1 ? fallbackQty : 1,
				}];
			}
			return [];
		},
		hasDrugs() {
			return this.drugRows.length > 0;
		},
		hasAnswers() {
			return Array.isArray(this.answerRecords) && this.answerRecords.length > 0;
		},
		/** 仅展示有数据的 Tab；基本信息始终保留 */
		visibleTabs() {
			const all = [
				{ key: 'basic', label: '基本信息' },
				{ key: 'drugs', label: '本次挂号选择药品', show: this.hasDrugs },
				{ key: 'answers', label: '回答记录', show: this.hasAnswers },
			];
			return all.filter((t) => t.show !== false);
		},
	},
	onLoad(options) {
		this.calcSwiperHeight();
		const id = Number((options && options.id) || 0);
		this.registerId = id;
		let cached = {};
		try {
			cached = uni.getStorageSync('user_patient_register_detail') || {};
		} catch (e) {
			cached = {};
		}
		// 缓存作乐观展示；id 不一致则只用 URL 中的 id
		if (cached && Number(cached.id) === id) {
			this.detail = cached;
		} else {
			this.detail = { id };
		}
		if (id) {
			this.loadDetail(id);
		}
	},
	onReady() {
		// 布局就绪后再算一次，避免状态栏/导航高度未就绪
		this.calcSwiperHeight();
	},
	methods: {
		/**
		 * 按窗口高度算死 swiper 高度：窗口 − 状态栏 − 导航 − Tab − 页边距
		 * 微信小程序 swiper 无明确高度时横向滑动常失效
		 */
		calcSwiperHeight() {
			try {
				const sys = uni.getSystemInfoSync() || {};
				const winH = Number(sys.windowHeight) || 600;
				const statusBar = Number(sys.statusBarHeight) || 0;
				const navbar = Number(this.$navbarHeight) || 44;
				const rpx = (Number(sys.windowWidth) || 375) / 750;
				const pagePad = Math.ceil(24 * rpx);
				const tabsH = Math.ceil(88 * rpx);
				const h = winH - statusBar - navbar - pagePad * 2 - tabsH;
				this.swiperHeightPx = h > 200 ? h : 200;
			} catch (e) {
				this.swiperHeightPx = 400;
			}
		},
		formatPrice(v) {
			const n = Number(v);
			return Number.isFinite(n) ? n.toFixed(2) : '0.00';
		},
		/** 无图时取药名首字作占位，与接诊面板一致 */
		drugThumbLetter(name) {
			const s = String(name || '').trim();
			return s ? s.charAt(0) : '药';
		},
		previewDrug(url) {
			if (!url) return;
			uni.previewImage({ urls: [url], current: url });
		},
		/**
		 * 点击顶部 Tab：同步 activeTab + tabIndex（与工作台 swiper 防抖一致）
		 */
		selectTab(index) {
			if (this.tabSwiperChanging) return;
			const tab = this.visibleTabs[index];
			if (!tab) return;
			this.tabIndex = index;
			this.activeTab = tab.key;
		},
		/**
		 * 左右滑动 swiper：同步 Tab 下标与 activeTab
		 */
		onTabSwiperChange(e) {
			const index = e && e.detail ? e.detail.current : 0;
			const tab = this.visibleTabs[index];
			if (!tab || tab.key === this.activeTab) return;
			this.tabSwiperChanging = true;
			this.tabIndex = index;
			this.activeTab = tab.key;
			this.$nextTick(() => {
				this.tabSwiperChanging = false;
			});
		},
		/**
		 * 按 activeTab 校正 tabIndex（数据加载后 Tab 集合可能变化）
		 */
		syncTabIndexFromActive() {
			const keys = this.visibleTabs.map((t) => t.key);
			let idx = keys.indexOf(this.activeTab);
			if (idx < 0) {
				this.activeTab = 'basic';
				idx = 0;
			}
			this.tabIndex = idx;
		},
		/**
		 * 多 Tab 时首次进入短暂提示「可左右滑动」；本地标记只提示一次
		 */
		maybeShowSwipeTip() {
			if (this.visibleTabs.length <= 1) return;
			let shown = '';
			try {
				shown = uni.getStorageSync(SWIPE_TIP_STORAGE_KEY);
			} catch (e) {
				shown = '';
			}
			if (shown) return;
			uni.showToast({
				title: '左右滑动可切换标签',
				icon: 'none',
				duration: 2000,
			});
			try {
				uni.setStorageSync(SWIPE_TIP_STORAGE_KEY, '1');
			} catch (e) {
				// 写缓存失败不影响主流程
			}
		},
		/** 拉取挂号详情并同步 Tab 可见性 */
		async loadDetail(id) {
			this.loading = true;
			try {
				const wrap = await getUserPatientRegisterDetail(id);
				if (!wrap || !wrap.ok || !wrap.data) {
					uni.showToast({ title: '挂号详情加载失败', icon: 'none' });
					return;
				}
				const data = wrap.data;
				this.detail = {
					id: data.id,
					order_no: data.order_no,
					order_number: data.order_number,
					store: data.store,
					doctor: data.doctor,
					type: data.type,
					type_text: data.type_text,
					status_text: data.status_text,
					price: data.price,
					is_pay: data.is_pay,
					created_at: data.created_at,
					pay_time: data.pay_time,
				};
				this.registerInfo = data.register_info || null;
				this.answerRecords = Array.isArray(data.answer_records) ? data.answer_records : [];
				this.syncTabIndexFromActive();
				this.calcSwiperHeight();
				this.$nextTick(() => {
					this.maybeShowSwipeTip();
				});
			} finally {
				this.loading = false;
			}
		},
	},
};
</script>

<style lang="scss" scoped>
.page {
	padding: 24rpx;
	box-sizing: border-box;
}
.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: 8rpx 24rpx;
	margin-bottom: 16rpx;
	padding: 0 4rpx;
}
.tab {
	position: relative;
	padding: 8rpx 0 12rpx;
}
.tab-text { font-size: 28rpx; color: #6b7280; }
.tab.on .tab-text { color: #1a9b88; font-weight: 600; }
.tab-bar {
	position: absolute; left: 20%; right: 20%; bottom: 0;
	height: 6rpx; border-radius: 6rpx; background: #6acdbb;
}
.tab-swiper {
	width: 100%;
}
.tab-scroll {
	width: 100%;
	box-sizing: border-box;
}
.card {
	background: #fff; border-radius: 20rpx; padding: 8rpx 24rpx;
}
.row {
	display: flex; justify-content: space-between; align-items: flex-start;
	padding: 24rpx 0; border-bottom: 1rpx solid #f3f4f6; gap: 24rpx;
}
.row:last-child { border-bottom: none; }
.answer-row .label { max-width: 46%; }
.label { font-size: 26rpx; color: #9ca3af; flex-shrink: 0; }
.value { font-size: 26rpx; color: #1f2937; text-align: right; flex: 1; word-break: break-all; }
.value.accent { color: #1a9b88; font-weight: 600; }
.drug-row {
	display: flex; align-items: flex-start; gap: 16rpx;
	padding: 24rpx 0; border-bottom: 1rpx solid #f3f4f6;
}
.drug-row:last-child { border-bottom: none; }
.drug-thumb {
	width: 72rpx; height: 72rpx; border-radius: 10rpx; background: #f3f4f6; flex-shrink: 0;
}
.drug-thumb-placeholder {
	display: flex; align-items: center; justify-content: center;
	background: #e5e7eb;
}
.drug-thumb-letter { font-size: 28rpx; color: #6b7280; font-weight: 600; }
.drug-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6rpx; }
.drug-name { font-size: 28rpx; color: #1f2937; font-weight: 500; }
.drug-spec { font-size: 22rpx; color: #9ca3af; }
.drug-qty { font-size: 28rpx; color: #1f2937; font-weight: 600; flex-shrink: 0; }
.empty { text-align: center; color: #9ca3af; padding: 80rpx 0; font-size: 28rpx; }
.empty-inline { text-align: center; color: #9ca3af; padding: 48rpx 0; font-size: 26rpx; }
</style>
