<template>
	<view class="exhibition-container">
		<!-- 背景图片 -->
		<image class="background-image" src="/static/background/ExhibitionBackground.png" mode="aspectFill"></image>
	
		<!-- Header组件 -->
		<Header :showBack="true" :showGuideIcon="false" :showTaskIcon="false" :showStarActivityIcon="false" backIconColor="#e6e6e6" />
		
		<!-- 展馆标题 -->
		<view class="gallery-owner-title">
			<text class="gallery-owner-title-text">
				{{ isViewingOthers ? (galleryOwnerNickname ? galleryOwnerNickname + '的展馆' : 'TA的展馆') : '我的展馆' }}
			</text>
			<view v-if="isViewingOthers" class="view-works-btn" @tap="goToHisWorks">
				<text class="view-works-btn-text">查看TA的作品</text>
			</view>
		</view>

		<!-- 展览板容器 -->
		<view class="exhibition-boards" :style="{ paddingTop: topPadding + 'rpx' }">
			<!-- 展览板1 -->
			<view class="exhibition-board">
				<image class="board-image" src="/static/components/frame1.png" mode="widthFix"></image>
				<view class="nft-cards-container">
					<template v-for="index in 3" :key="`board1-${index}`">
						<!-- 获取对应位置的藏品 -->
						<template v-if="friendExhibitions[index - 1] && friendExhibitions[index - 1].image">
							<!-- 有藏品：显示藏品卡片 -->
							<NftCard
								:cover-image="friendExhibitions[index - 1].image"
								:width="getNftCardSize()"
								:height="getNftCardSize()"
								:custom-style="getNftCardStyle(index, 1)"
								:visibility="friendExhibitions[index - 1].visibility || 'public'"
								:operation="friendExhibitions[index - 1].operation || 'none'"
								@click="handleNftClick(friendExhibitions[index - 1])"
								@longpress="handleLongPress($event, friendExhibitions[index - 1])"
							/>
							<!-- 倒计时背景 -->
							<view class="countdown-background" :style="getCountdownBackgroundStyle(index, 1)"></view>
							<!-- 倒计时文字 -->
							<text class="countdown-text" :style="getCountdownStyle(index, 1)">
								{{ formatCountdown(friendExhibitions[index - 1].id) }}
							</text>
							<!-- 点赞数（左下角） -->
							<view class="like-badge" :style="getLikeBadgeStyle(index, 1)">
								<image class="like-icon" src="/static/icon/heart-icon.png" mode="aspectFit"></image>
								<view class="like-count-background">
									<text class="like-count-text">{{ formatLikeCount(friendExhibitions[index - 1].like_count) }}</text>
								</view>
							</view>
					</template>
					<template v-else>
						<!-- 无藏品：根据can_operate判断是否显示添加按钮 -->
						<NftCard
							:cover-image="''"
							:width="getNftCardSize()"
							:height="getNftCardSize()"
							:custom-style="getNftCardStyle(index, 1)"
							:show-add-button="getSlotCanOperate(1, index).operation === 'place'"
							:visibility="'public'"
							:operation="getSlotCanOperate(1, index).operation"
							@add="handleAddAssetClick(index, 1)"
						/>
					</template>
					</template>
				</view>
				<text class="board-label">共享展位</text>
			</view>
			
			<!-- 展览板2 -->
			<view class="exhibition-board nft-cards-container-2">
				<image class="board-image" src="/static/components/frame2.png" mode="widthFix"></image>
				<view class="nft-cards-container">
					<template v-for="index in 3" :key="`board2-${index}`">
					<!-- 获取对应位置的藏品 -->
					<template v-if="myExhibitions[index - 1]">
						<!-- 有藏品：显示藏品卡片 -->
						<NftCard
							:cover-image="myExhibitions[index - 1].image"
							:width="getNftCardSize()"
							:height="getNftCardSize()"
							:custom-style="getNftCardStyle(index, 2)"
							:visibility="myExhibitions[index - 1].visibility || 'private'"
							:operation="myExhibitions[index - 1].operation || 'none'"
							@click="handleNftClick(myExhibitions[index - 1])"
							@longpress="handleLongPress($event, myExhibitions[index - 1])"
						/>
						<!-- 倒计时背景 -->
						<view class="countdown-background" :style="getCountdownBackgroundStyle(index, 2)"></view>
						<!-- 倒计时文字 -->
						<text class="countdown-text" :style="getCountdownStyle(index, 2)">
							{{ formatCountdown(myExhibitions[index - 1].id) }}
						</text>
						<!-- 点赞数（左下角） -->
						<view class="like-badge" :style="getLikeBadgeStyle(index, 2)">
							<image class="like-icon" src="/static/icon/heart-icon.png" mode="aspectFit"></image>
							<view class="like-count-background">
								<text class="like-count-text">{{ formatLikeCount(myExhibitions[index - 1].like_count) }}</text>
							</view>
						</view>
				</template>
					<template v-else>
						<!-- 无藏品：根据can_operate判断是否显示添加按钮 -->
						<NftCard
							:cover-image="''"
							:width="getNftCardSize()"
							:height="getNftCardSize()"
							:custom-style="getNftCardStyle(index, 2)"
							:show-add-button="getSlotCanOperate(2, index).operation === 'place'"
							:visibility="'private'"
							:operation="getSlotCanOperate(2, index).operation"
							@add="handleAddAssetClick(index, 2)"
						/>
					</template>
					</template>
				</view>
				<text class="board-label board-label-right">{{ isMyGallery ? '我的展位' : 'TA的展位' }}</text>
		</view>
		
		
		</view>
		<!-- 底部按钮：动态显示 -->
		<button class="castlove-btn" :style="{ bottom: bottomPadding + 'rpx' }" @click="handleBottomButtonClick">
			{{ isMyGallery ? '铸爱' : '返回我的展馆' }}
		</button>
	<!-- 随机展馆左右箭头 -->
	<view class="random-gallery-arrows">
		<view class="arrow-btn arrow-left" @click="loadRandomGallery">
			<text class="arrow-text">‹</text>
		</view>
		<view class="arrow-btn arrow-right" @click="loadRandomGallery">
			<text class="arrow-text">›</text>
		</view>
	</view>

	<!-- 左下角角色图片 -->
	<image class="character-image" src="/static/icon/exhibition-char.png" mode="widthFix"></image>
		
	<!-- 藏品选择弹窗 -->
	<view v-if="showAssetSelectModal" class="asset-select-modal-mask" @tap="closeAssetSelectModal">
			<view
				class="asset-select-modal"
				@tap.stop
				:class="{ 'show': assetSelectModalAnimated }"
			>
				<!-- 背景图片 -->
				<image class="modal-background-image" src="/static/background/starbook.jpg" mode="aspectFill"></image>

				<!-- 内容包装器 -->
				<view class="modal-content-wrapper">
					<!-- 顶部拖动区域 -->
					<view
						class="modal-top-drag-area"
						@touchstart="handleModalTouchStart"
						@touchmove="handleModalTouchMove"
						@touchend="handleModalTouchEnd"
					>
						<!-- 顶部拖动条 -->
						<view class="modal-handle"></view>

						<!-- 标题 -->
						<text class="modal-title">选择要展出的藏品</text>
					</view>

					<!-- 类型Tab -->
					<view class="modal-type-tabs">
						<view
							class="modal-tab-item"
							:class="{ active: modalCurrentType === 'regular' }"
							@click="switchModalType('regular')"
						>
							<text>原创</text>
						</view>
						<view
							class="modal-tab-item"
							:class="{ active: modalCurrentType === 'collection' }"
							@click="switchModalType('collection')"
						>
							<text>典藏</text>
						</view>
						<view
							class="modal-tab-item"
							:class="{ active: modalCurrentType === 'activity' }"
							@click="switchModalType('activity')"
						>
							<text>活动</text>
						</view>
					</view>

					<!-- 加载中 -->
					<view v-if="modalLoading" class="modal-loading-container">
						<text class="modal-loading-text">加载中...</text>
					</view>

					<!-- 空状态 -->
					<view v-else-if="!modalHasData" class="modal-empty-container">
						<text class="modal-empty-text">暂无藏品</text>
					</view>

					<!-- 藏品列表 - 与星册一致的水平滚动布局 -->
					<scroll-view v-else class="modal-nft-scroll-view" scroll-y :show-scrollbar="false">
						<view class="modal-nft-list-container">
							<!-- 原创藏品：按 grade 分组 -->
							<template v-if="modalCurrentType === 'regular'">
								<view v-for="gradeItem in modalRegularGrades" :key="gradeItem.grade" class="modal-grade-section">
									<view class="modal-group-header">
										<text class="modal-group-title">{{ formatModalGrade(gradeItem.grade) }}</text>
									</view>
									<scroll-view class="modal-nft-row" scroll-x :show-scrollbar="false" :enable-flex="true">
										<view class="modal-nft-row-content">
											<view
												v-for="item in gradeItem.items"
												:key="item.asset_id"
												class="modal-nft-grid-item"
												@click.stop="handleAssetSelect(item)"
											>
												<image
													class="modal-nft-image"
													:src="item.coverUrl || '/static/nft/collection.png'"
													mode="aspectFill"
												/>
												<view class="modal-status-badge" :class="item.display_status === 1 ? 'modal-status-badge-active' : 'modal-status-badge-pending'">
													<text class="modal-status-text">{{ item.display_status === 1 ? '已展示' : '待展示' }}</text>
												</view>
												<view class="modal-nft-info">
													<text class="modal-nft-name">{{ item.name }}</text>
												</view>
											</view>
										</view>
									</scroll-view>
								</view>
							</template>

							<!-- 典藏藏品：直接列表 -->
							<template v-else-if="modalCurrentType === 'collection'">
								<view class="modal-grade-section">
									<scroll-view class="modal-nft-row" scroll-x :show-scrollbar="false" :enable-flex="true">
										<view class="modal-nft-row-content">
											<view
												v-for="item in modalCollectionItems"
												:key="item.asset_id"
												class="modal-nft-grid-item"
												@click.stop="handleAssetSelect(item)"
											>
												<image
													class="modal-nft-image"
													:src="item.coverUrl || '/static/nft/collection.png'"
													mode="aspectFill"
												/>
												<view class="modal-status-badge" :class="item.display_status === 1 ? 'modal-status-badge-active' : 'modal-status-badge-pending'">
													<text class="modal-status-text">{{ item.display_status === 1 ? '已展示' : '待展示' }}</text>
												</view>
												<view class="modal-nft-info">
													<text class="modal-nft-name">{{ item.name }}</text>
												</view>
											</view>
										</view>
									</scroll-view>
								</view>
							</template>

							<!-- 活动藏品：直接列表 -->
							<template v-else-if="modalCurrentType === 'activity'">
								<view class="modal-grade-section">
									<scroll-view class="modal-nft-row" scroll-x :show-scrollbar="false" :enable-flex="true">
										<view class="modal-nft-row-content">
											<view
												v-for="item in modalActivityItems"
												:key="item.asset_id"
												class="modal-nft-grid-item"
												@click.stop="handleAssetSelect(item)"
											>
												<image
													class="modal-nft-image"
													:src="item.coverUrl || '/static/nft/collection.png'"
													mode="aspectFill"
												/>
												<view class="modal-status-badge" :class="item.display_status === 1 ? 'modal-status-badge-active' : 'modal-status-badge-pending'">
													<text class="modal-status-text">{{ item.display_status === 1 ? '已展示' : '待展示' }}</text>
												</view>
												<view class="modal-nft-info">
													<text class="modal-nft-name">{{ item.name }}</text>
												</view>
											</view>
										</view>
									</scroll-view>
								</view>
							</template>
						</view>
					</scroll-view>
				</view>
			</view>
	</view>
		
	<!-- 上架确认弹窗 -->
	<view v-if="showPlaceConfirmModal" class="place-confirm-modal-mask" @tap="closePlaceConfirmModal">
		<view class="place-confirm-modal" @tap.stop>
			<text class="confirm-title">{{ isReplaceMode ? '确认替换藏品？' : '确认展出藏品？' }}</text>
			
			<view class="confirm-content">
				<view class="confirm-row">
					<text class="confirm-label">藏品ID:</text>
					<text class="confirm-value">{{ selectedAssetForPlace?.asset_id }}</text>
				</view>
				<view class="confirm-row">
					<text class="confirm-label">藏品名称:</text>
					<text class="confirm-value">{{ selectedAssetForPlace?.name || '未知' }}</text>
				</view>
				<view class="confirm-row">
					<text class="confirm-label">展出位置:</text>
					<text class="confirm-value">slotID: {{ selectedSlotId }}</text>
				</view>
			</view>
			
			<view class="confirm-buttons">
				<button class="confirm-btn cancel-btn" @tap="closePlaceConfirmModal">取消</button>
				<button class="confirm-btn submit-btn" @tap="confirmPlaceAsset">确认</button>
			</view>
		</view>
	</view>
	
	<!-- 下架确认弹窗 -->
	<view v-if="showRemoveConfirmModal" class="place-confirm-modal-mask" @tap="closeRemoveConfirmModal">
		<view class="place-confirm-modal" @tap.stop>
			<text class="confirm-title">确认下架藏品？</text>
			
			<view class="confirm-content">
				<view class="confirm-row">
					<text class="confirm-label">藏品ID:</text>
					<text class="confirm-value">{{ selectedAssetForRemove?.asset_id }}</text>
				</view>
				<view class="confirm-row">
					<text class="confirm-label">藏品名称:</text>
					<text class="confirm-value">{{ selectedAssetForRemove?.name || '未知' }}</text>
				</view>
				<view class="confirm-row">
					<text class="confirm-label">展出位置:</text>
					<text class="confirm-value">slotID: {{ selectedAssetForRemove?.slot_id }}</text>
				</view>
			</view>
			
			<view class="confirm-buttons">
				<button class="confirm-btn cancel-btn" @tap="closeRemoveConfirmModal">取消</button>
				<button class="confirm-btn submit-btn" @tap="confirmRemoveAsset">确认下架</button>
			</view>
		</view>
	</view>
	<!-- 全局引导遮罩 -->
		<GuideOverlay />
</view>
</template>

<script>
export default {
	onBackPress(options) {
		// 获取当前页面实例
		const pages = getCurrentPages();
		const currentPage = pages[pages.length - 1];
		
		// 如果藏品选择弹窗打开，关闭弹窗而不是返回上一页
		if (currentPage.$vm && currentPage.$vm.showAssetSelectModal && currentPage.$vm.showAssetSelectModal.value) {
			currentPage.$vm.closeAssetSelectModal();
			return true; // 返回 true 表示已处理，阻止默认返回行为
		}
		
		return false; // 返回 false 表示未处理，执行默认返回行为
	}
};
</script>

<script setup>
	import { ref, computed, onMounted, onUnmounted, getCurrentInstance } from 'vue';
	import { onLoad } from '@dcloudio/uni-app';
	import { useStore } from 'vuex';
	import Header from '../components/Header.vue';
	import NftCard from '../components/NftCard.vue';
	import { getMyGalleriesApi, placeAssetToGalleryApi, getMyAssetsApi, removeAssetFromGalleryApi, getUserGalleriesApi, getRandomGalleryApi } from '@/utils/api.js';
	import { getAssetCoverRealUrl } from '@/utils/assetImageHelper.js';
	import { reportEvent } from '@/utils/task-api.js';
	import GuideOverlay from "@/components/GuideOverlay.vue";

	const store = useStore();
	// 屏幕宽度和高度
	const screenWidth = ref(0);
	const screenHeight = ref(0);
	// 顶部距离（屏幕高度的14%）
	const topPadding = ref(0);
	// 底部距离（屏幕高度的5%）
	const bottomPadding = ref(0);
	
	// 共享展位藏品数据（展览板1）
	const friendExhibitions = ref([
		{
		id: 'friend_1',
		asset_id: 'NFT001',
		cover_url: '/static/nft/collection.png',
		owner_uid: '10001',
			owner_nickname: '好友昵称',
			name: '友谊之光',
			tx_hash: '0x1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890',
			block_number: '12345678',
			like_count: 128,
			is_liked: false,
			startTime: Date.now(), // 展出开始时间戳
			duration: 8 * 60 * 60 * 1000 // 8小时（毫秒）
		}
	]);
	
	// 我的展位藏品数据（展览板2）
	const myExhibitions = ref([
		{
			
		}
	]);
	
	// 倒计时状态
	const countdowns = ref({});
	
	// 展馆相关状态
	const galleryOwnerId = ref(null);
	const gallerySlots = ref([]);

	// 获取指定槽位的can_operate信息（用于空槽位）
	const getSlotCanOperate = (boardType, index) => {
		// 按 slot_index 排序后再按位置选择
		const publicSlots = gallerySlots.value
			.filter(slot => slot.visibility === 'public')
			.sort((a, b) => a.slot_index - b.slot_index);
		const privateSlots = gallerySlots.value
			.filter(slot => slot.visibility === 'private')
			.sort((a, b) => a.slot_index - b.slot_index);
		const slots = boardType === 1 ? publicSlots : privateSlots;
		const slot = slots[index - 1];
		if (!slot) return { can_operate: false, operation: 'none' };
		return {
			can_operate: slot.can_operate || false,
			operation: slot.operation || 'none'
		};
	};

	const showAssetSelectModal = ref(false);
	const assetSelectModalAnimated = ref(false); // 控制弹窗动画
	const selectedSlotId = ref(null);
	const selectedSlotIndex = ref(null);
	const showPlaceConfirmModal = ref(false);
	const selectedAssetForPlace = ref(null);
	const myAssetsGroups = ref([]); // 分组后的藏品数据
	const modalLoading = ref(false); // 弹窗内藏品加载状态
	const modalCurrentType = ref('regular'); // 当前选中的类型

	// 计算当前类型是否有数据
	const modalHasData = computed(() => {
		const groups = myAssetsGroups.value;
		if (modalCurrentType.value === 'regular') {
			const group = groups.find(g => g.type === 'regular');
			return group && group.grades && group.grades.some(g => g.items && g.items.length > 0);
		} else if (modalCurrentType.value === 'collection') {
			const group = groups.find(g => g.type === 'collection');
			return group && group.items && group.items.length > 0;
		} else if (modalCurrentType.value === 'activity') {
			const group = groups.find(g => g.type === 'activity');
			return group && group.items && group.items.length > 0;
		}
		return false;
	});

	// 获取原创藏品的等级分组
	const modalRegularGrades = computed(() => {
		const group = myAssetsGroups.value.find(g => g.type === 'regular');
		return group && group.grades ? group.grades : [];
	});

	// 获取典藏藏品列表
	const modalCollectionItems = computed(() => {
		const group = myAssetsGroups.value.find(g => g.type === 'collection');
		return group && group.items ? group.items : [];
	});

	// 获取活动藏品列表
	const modalActivityItems = computed(() => {
		const group = myAssetsGroups.value.find(g => g.type === 'activity');
		return group && group.items ? group.items : [];
	});

	// grade 中文转换
	const gradeMap = { 1: '一', 2: '二', 3: '三', 4: '四', 5: '五' };
	const formatModalGrade = (grade) => {
		return `等级${gradeMap[grade] || grade}`;
	};

	// 切换弹窗内类型
	const switchModalType = (type) => {
		modalCurrentType.value = type;
	};
	
	// 下架藏品相关状态
	const showRemoveConfirmModal = ref(false);
	const selectedAssetForRemove = ref(null);

	// 替换藏品相关状态
	const isReplaceMode = ref(false);
	
	// 访问其他用户展馆相关状态
	// 当前访问的展馆所有者UID
	const visitingGalleryOwnerUid = ref(null);
	// 展馆主人昵称（仅访问他人展馆时有值）
	const galleryOwnerNickname = ref('');
	// 是否是通过 target_uid 进入他人展馆（onLoad 时确定，不随 parseGalleryResponse 变化）
	const isViewingOthers = ref(false);
	// 当前用户UID
	const currentUserUid = ref(null);
	// 是否是访问自己的展馆
	const isMyGallery = computed(() => {
		if (!currentUserUid.value || !visitingGalleryOwnerUid.value) {
			return true; // 默认为true，避免闪烁
		}
		return currentUserUid.value === visitingGalleryOwnerUid.value;
	});

	// 弹窗滑动关闭相关状态
	const modalTouchStartY = ref(0);
	const modalTouchStartTime = ref(0);
	const modalScrollTop = ref(0);
	
	// 获取NFT卡片尺寸
	const getNftCardSize = () => {
		// 根据屏幕宽度计算，放大槽位尺寸
		return screenWidth.value * 0.33;
	};
	
	// 计算藏品选择弹窗中的卡片尺寸（与星册页面保持一致）
	const cardSize = computed(() => {
		if (screenWidth.value === 0) return 200;
		const rpxToPx = screenWidth.value / 750;
		const padding = 40 * rpxToPx;
		const gap = 15 * rpxToPx;
		const availableWidth = screenWidth.value - (padding * 2) - (gap * 2);
		return Math.floor(availableWidth / 3);
	});
	
	// 卡片自定义样式（与星册页面保持一致）
	const cardCustomStyle = {
		position: 'absolute',
		top: '0',
		left: '0'
	};
	
	// 计算顶部和底部距离
	const calculateTopPadding = () => {
		if (screenHeight.value === 0 || screenWidth.value === 0) return;
		// rpx转换比例：750rpx = 屏幕宽度
		const pxToRpx = 750 / screenWidth.value;
		topPadding.value = screenHeight.value * 0.14 * pxToRpx;
		bottomPadding.value = screenHeight.value * 0.05 * pxToRpx;
	};
	
	// 获取NFT卡片样式（位置）
	const getNftCardStyle = (index, boardNumber) => {
		const cardSize = getNftCardSize();
		const containerWidth = screenWidth.value;
		
		// 计算三个卡片的位置，水平均匀分布
		// 第一个卡片在左侧，第二个在中间，第三个在右侧
		let leftPercent = 0;
		if (index === 1) {
			leftPercent = 25; // 左侧
		} else if (index === 2) {
			leftPercent = 50; // 中间
		} else {
			leftPercent = 75; // 右侧
		}
		
		// 垂直位置，根据展览板调整
		let topPercent = 50; // 默认居中
		if (boardNumber === 1) {
			topPercent = 42; // 第一个展览板下移
		} else {
			topPercent = 54; // 第二个展览板下移
		}
		
		return {
			position: 'absolute',
			left: `${leftPercent}%`,
			top: `${topPercent}%`,
			transform: 'translate(-50%, -50%)'
		};
	};
	
	// 过滤已过期的藏品
	const filterExpiredExhibitions = async () => {
		let hasExpired = false;

		// 过滤展览板1（共享展位/公开展位）
		// 关键：使用 map 而不是 filter，保持数组长度和槽位对应关系
		friendExhibitions.value = friendExhibitions.value.map(item => {
			if (!item) return null;

			// 如果有 remainSeconds 字段，检查是否过期
			if (item.remainSeconds !== undefined) {
				const isExpired = item.remainSeconds <= 0;
				if (isExpired) hasExpired = true;
				return isExpired ? null : item;
			}

			// 兼容旧的时间戳方式
			if (item.startTime && item.duration) {
				const now = Date.now();
				const isExpired = now - item.startTime >= item.duration;
				if (isExpired) hasExpired = true;
				return isExpired ? null : item;
			}

			return null;
		});

		// 过滤展览板2（我的展位/私密展位）
		// 关键：使用 map 而不是 filter，保持数组长度和槽位对应关系
		myExhibitions.value = myExhibitions.value.map(item => {
			if (!item) return null;

			// 如果有 remainSeconds 字段，检查是否过期
			if (item.remainSeconds !== undefined) {
				const isExpired = item.remainSeconds <= 0;
				if (isExpired) hasExpired = true;
				return isExpired ? null : item;
			}

			// 兼容旧的时间戳方式
			if (item.startTime && item.duration) {
				const now = Date.now();
				const isExpired = now - item.startTime >= item.duration;
				if (isExpired) hasExpired = true;
				return isExpired ? null : item;
			}

			return null;
		});

		// 如果有藏品过期，刷新 gallerySlots 数据以更新槽位状态
		if (hasExpired) {
			await loadGallerySlots();
		}
	};
	
	// 计算剩余时间
	const calculateRemainingTime = (item) => {
		// 如果有 remainSeconds 字段，直接使用（单位：秒）
		if (item.remainSeconds !== undefined) {
			if (item.remainSeconds <= 0) {
				return { hours: 0, minutes: 0, seconds: 0, expired: true };
			}
			
			const hours = Math.floor(item.remainSeconds / 3600);
			const minutes = Math.floor((item.remainSeconds % 3600) / 60);
			const seconds = Math.floor(item.remainSeconds % 60);
			
			return { hours, minutes, seconds, expired: false };
		}
		
		// 兼容旧的时间戳方式（用于共享展位）
		if (item.startTime && item.duration) {
			const now = Date.now();
			const elapsed = now - item.startTime;
			const remaining = item.duration - elapsed;
			
			if (remaining <= 0) {
				return { hours: 0, minutes: 0, seconds: 0, expired: true };
			}
			
			const hours = Math.floor(remaining / (60 * 60 * 1000));
			const minutes = Math.floor((remaining % (60 * 60 * 1000)) / (60 * 1000));
			const seconds = Math.floor((remaining % (60 * 1000)) / 1000);
			
			return { hours, minutes, seconds, expired: false };
		}
		
		// 默认返回过期状态
		return { hours: 0, minutes: 0, seconds: 0, expired: true };
	};
	
	// 更新所有倒计时
	const updateCountdowns = () => {
		// 更新共享展位倒计时，并减少 remainSeconds
		[...friendExhibitions.value].forEach(item => {
			// 跳过空槽位（null）
			if (item && item.id) {
				// 如果有 remainSeconds，每秒减1
				if (item.remainSeconds !== undefined && item.remainSeconds > 0) {
					item.remainSeconds--;
				}
				countdowns.value[item.id] = calculateRemainingTime(item);
			}
		});
		
		// 更新我的展位倒计时，并减少 remainSeconds
		[...myExhibitions.value].forEach(item => {
			if (item && item.id) {
				// 如果有 remainSeconds，每秒减1
				if (item.remainSeconds !== undefined && item.remainSeconds > 0) {
					item.remainSeconds--;
				}
				countdowns.value[item.id] = calculateRemainingTime(item);
			}
		});
		
		// 移除过期藏品
		filterExpiredExhibitions();
	};
	
	// 获取倒计时样式（位于卡片左上角）
	const getCountdownStyle = (index, boardNumber) => {
		const cardStyle = getNftCardStyle(index, boardNumber);
		const cardSize = getNftCardSize();
		const backgroundWidth = cardSize * 0.58;
		const backgroundHeight = cardSize * 0.16;
		const insetY = cardSize * 0.1;
		const rightOffset = cardSize * 0.08;
		// 让倒计时左边缘与卡片左边缘严格对齐
		const translateX = -cardSize / 2 + backgroundWidth / 2 + rightOffset;
		const translateY = -cardSize / 2 + insetY;
		return {
			position: 'absolute',
			left: cardStyle.left,
			top: cardStyle.top,
			width: `${backgroundWidth}px`,
			height: `${backgroundHeight}px`,
			transform: `translate(calc(-50% + ${translateX}px), calc(-50% + ${translateY}px))`,
			pointerEvents: 'none',
			display: 'flex',
			alignItems: 'center',
			justifyContent: 'center'
		};
	};
	
	// 获取倒计时背景样式（位于卡片左上角）
	const getCountdownBackgroundStyle = (index, boardNumber) => {
		const cardStyle = getNftCardStyle(index, boardNumber);
		const cardSize = getNftCardSize();
		const backgroundWidth = cardSize * 0.58;
		const backgroundHeight = cardSize * 0.16;
		const insetY = cardSize * 0.1;
		const rightOffset = cardSize * 0.08;
		// 让倒计时左边缘与卡片左边缘严格对齐
		const translateX = -cardSize / 2 + backgroundWidth / 2 + rightOffset;
		const translateY = -cardSize / 2 + insetY;
		return {
			position: 'absolute',
			left: cardStyle.left,
			top: cardStyle.top,
			width: `${backgroundWidth}px`,
			height: `${backgroundHeight}px`,
			transform: `translate(calc(-50% + ${translateX}px), calc(-50% + ${translateY}px))`,
			pointerEvents: 'none'
		};
	};
	
	// 格式化倒计时显示
	const formatCountdown = (itemId) => {
		const countdown = countdowns.value[itemId];
		if (!countdown || countdown.expired) return '00:00:00';
		
		const h = String(countdown.hours).padStart(2, '0');
		const m = String(countdown.minutes).padStart(2, '0');
		const s = String(countdown.seconds).padStart(2, '0');
		
		return `${h}:${m}:${s}`;
	};

	// 获取点赞徽标样式（位于卡片左下角）
	const getLikeBadgeStyle = (index, boardNumber) => {
		const cardStyle = getNftCardStyle(index, boardNumber);
		const cardSize = getNftCardSize();
		const iconSize = cardSize * 0.23;
		const insetX = iconSize * 1.55;
		const insetY = iconSize * 0.55;
		const translateX = -cardSize / 2 + insetX;
		const translateY = cardSize / 2 - insetY;
		return {
			position: 'absolute',
			left: cardStyle.left,
			top: cardStyle.top,
			transform: `translate(calc(-50% + ${translateX}px), calc(-50% + ${translateY}px))`,
			pointerEvents: 'none',
			display: 'flex',
			alignItems: 'center',
			gap: `${Math.max(4, cardSize * 0.02)}px`
		};
	};

	// 格式化点赞数显示
	const formatLikeCount = (likeCount) => {
		const numericLikeCount = Number(likeCount);
		if (!Number.isFinite(numericLikeCount) || numericLikeCount < 0) {
			return '0';
		}
		return `${Math.floor(numericLikeCount)}`;
	};
	
	// 点击藏品卡片，跳转到详情页
	const handleNftClick = (nft) => {
		if (!nft || !nft.asset_id) return;
		uni.navigateTo({
			url: `/pages/asset-detail/asset-detail?asset_id=${nft.asset_id}`
		});
	};
	
	// 跳转到铸爱页面
	const goToCastlove = () => {
		uni.navigateTo({
			url: '/pages/castlove/mall'
		});
	};

	// 跳转到查看TA的作品页面
	const goToHisWorks = () => {
		if (!galleryOwnerId.value || !galleryOwnerNickname.value) return;
		uni.navigateTo({
			url: `/pages/profile/hisWorks?userId=${galleryOwnerId.value}&nickname=${encodeURIComponent(galleryOwnerNickname.value)}`
		});
	};

	// 处理底部按钮点击
	const handleBottomButtonClick = async () => {
		if (isMyGallery.value) {
			// 访问自己的展馆，跳转到铸爱页面
			goToCastlove();
		} else {
			// 访问他人展馆，返回自己的展馆
			// 先确保 currentUserUid 有值
			if (!currentUserUid.value) {
				const userStr = uni.getStorageSync('user');
				if (userStr) {
					try {
						const user = JSON.parse(userStr);
						currentUserUid.value = user.uid;
					} catch (e) {
						console.error('解析用户信息失败:', e);
					}
				}
			}

			// 先清空状态，确保 UI 先更新
			isViewingOthers.value = false;
			visitingGalleryOwnerUid.value = currentUserUid.value;
			galleryOwnerNickname.value = '';

			// 强制更新 DOM
			await new Promise(resolve => setTimeout(resolve, 0));

			// 再加载数据
			loadGallerySlots();
		}
	};
	
	// 加载展馆槽位信息
	// 将 API 响应解析并填充到展馆数据中（供 loadGallerySlots 和 loadRandomGallery 共用）
	const parseGalleryResponse = async (data) => {
		console.log('parseGalleryResponse called', {
			isViewingOthers: isViewingOthers.value,
			dataGalleryOwnerId: data.gallery_owner_id,
			currentUserUid: currentUserUid.value
		});

		// 只更新展馆所有者信息，不要修改 isViewingOthers
		// isViewingOthers 只在 onLoad 时设置，避免状态混乱
		visitingGalleryOwnerUid.value = data.gallery_owner_id;
		galleryOwnerNickname.value = data.nickname || '';

		galleryOwnerId.value = data.gallery_owner_id;
		uni.setStorageSync('gallery_owner_id', data.gallery_owner_id);

		gallerySlots.value = data.slots || [];

		// 按 slot_index 排序，确保展位按顺序处理
		const publicSlots = gallerySlots.value
			.filter(slot => slot.visibility === 'public')
			.sort((a, b) => a.slot_index - b.slot_index);
		const privateSlots = gallerySlots.value
			.filter(slot => slot.visibility === 'private')
			.sort((a, b) => a.slot_index - b.slot_index);

		const buildExhibitionItem = async (slot, index) => {
			if (index >= 3 || slot.status !== 'OCCUPIED' || !slot.asset) return null;
			const realCoverUrl = await getAssetCoverRealUrl(slot.asset.cover_url);
			return {
				id: `slot_${slot.slot_id}_${slot.asset.asset_id}`,
				asset_id: slot.asset.asset_id,
				name: slot.asset.name,
				image: realCoverUrl,
				cover_url: slot.asset.cover_url || '/static/nft/collection.png',
				like_count: slot.asset.like_count || 0,
				slot_id: slot.slot_id,
				slot_index: slot.slot_index,
				visibility: slot.visibility,
				can_operate: slot.can_operate || false,
				operation: slot.operation || 'none',
				remainSeconds: slot.asset.remain_time || 0,
				occupied_at: slot.occupied_at,
				expire_at: slot.expire_at,
				occupier_uid: slot.occupier_uid
			};
		};

		friendExhibitions.value = new Array(3).fill(null);
		const publicResults = await Promise.all(publicSlots.map(buildExhibitionItem));
		publicResults.forEach((item, i) => { if (item) friendExhibitions.value[i] = item; });

		myExhibitions.value = new Array(3).fill(null);
		const privateResults = await Promise.all(privateSlots.map(buildExhibitionItem));
		privateResults.forEach((item, i) => { if (item) myExhibitions.value[i] = item; });
	};

	const loadGallerySlots = async () => {
		console.log('loadGallerySlots called', {
			isViewingOthers: isViewingOthers.value,
			visitingGalleryOwnerUid: visitingGalleryOwnerUid.value,
			currentUserUid: currentUserUid.value
		});
		try {
			let response;
			// 根据 visitingGalleryOwnerUid 是否等于 currentUserUid 来判断是否调用自己的展馆 API
			// 这样可以避免 isViewingOthers 状态错误导致的 API 调用错误
			if (visitingGalleryOwnerUid.value === currentUserUid.value) {
				response = await getMyGalleriesApi();
			} else {
				response = await getUserGalleriesApi(visitingGalleryOwnerUid.value);
			}

			if (response.code === 200 && response.data) {
				await parseGalleryResponse(response.data);
			}
		} catch (error) {
			console.error('获取展馆槽位信息失败:', error);
			uni.showToast({
				title: error.message || '获取展馆信息失败',
				icon: 'none',
				duration: 2000
			});
		}
	};
	
	// 加载随机用户展馆（点击左右箭头触发）
	const loadRandomGallery = async () => {
		try {
			const response = await getRandomGalleryApi();
			console.log(response)
			if (response.code === 200 && response.data) {
				// 加载随机展馆时，需要设置 isViewingOthers 为 true
				isViewingOthers.value = response.data.gallery_owner_id !== currentUserUid.value;
				await parseGalleryResponse(response.data);
			}
		} catch (error) {
			console.error('获取随机展馆失败:', error);
			uni.showToast({
				title: error.message || '获取随机展馆失败',
				icon: 'none',
				duration: 2000
			});
		}
	};

	// 处理添加藏品点击（展览板的加号按钮）
	// slotIndex: 页面上的位置索引（1-based，即1、2、3）
	// boardNumber: 展览板编号（1或2）
	const handleAddAssetClick = async (slotIndex, boardNumber = 2) => {
		// 根据展览板编号确定 visibility
		const targetVisibility = boardNumber === 1 ? 'public' : 'private';

		// 找到对应 visibility 的槽位，并根据页面位置索引匹配
		// 按 slot_index 排序后再按位置选择
		const slotsWithTargetVisibility = gallerySlots.value
			.filter(s => s.visibility === targetVisibility)
			.sort((a, b) => a.slot_index - b.slot_index);

		// slotIndex 是页面位置（1-based），对应数组索引为 slotIndex - 1
		const slot = slotsWithTargetVisibility[slotIndex - 1];
		
		if (!slot) {
			uni.showToast({
				title: '槽位信息不存在',
				icon: 'none',
				duration: 2000
			});
			return;
		}
		
		selectedSlotId.value = slot.slot_id;
		selectedSlotIndex.value = slot.slot_index;


		// 获取用户藏品列表
		modalLoading.value = true;
		try {
			const response = await getMyAssetsApi(1, 20);
			if (response.code === 200 && response.data && response.data.data.groups) {
				// 先展示弹窗，再异步处理图片
				showAssetSelectModal.value = true;
				setTimeout(() => {
					assetSelectModalAnimated.value = true;
				}, 50);

				// 收集所有需要处理的藏品项
				const allItems = [];
				const itemRefs = [];

				// 处理分组数据，收集 items 稍后并行处理
				const processedGroups = [];
				for (const group of response.data.data.groups) {
					const processedGroup = {
						type: group.type,
						category: group.category,
						category_name: group.category_name,
						total_count: group.total_count,
						has_more: group.has_more,
						grades: [],
						items: []
					};

					// 处理 grades
					if (group.grades) {
						for (const grade of group.grades) {
							const processedGrade = {
								grade: grade.grade,
								total_count: grade.total_count,
								has_more: grade.has_more,
								items: []
							};
							for (const item of grade.items || []) {
								allItems.push(item);
								itemRefs.push({ type: 'grade', parent: processedGrade, grade: item.grade, category: null });
							}
							processedGroup.grades.push(processedGrade);
						}
					}

					// 处理 items
					if (group.items) {
						for (const item of group.items) {
							allItems.push(item);
							itemRefs.push({ type: 'item', parent: processedGroup, grade: null, category: item.category });
						}
					}

					processedGroups.push(processedGroup);
				}

				// 并行处理所有封面URL
				const coverUrlPromises = allItems.map(item => getAssetCoverRealUrl(item.cover_url_signed));
				const coverUrls = await Promise.all(coverUrlPromises);

				// 将处理好的封面URL填回数据结构
				for (let i = 0; i < allItems.length; i++) {
					const item = allItems[i];
					const ref = itemRefs[i];
					const processedItem = {
						asset_id: item.asset_id,
						name: item.name,
						coverUrl: coverUrls[i],
						display_status: item.display_status || 0,
						like_count: item.like_count,
						grade: ref.grade,
						category: ref.category
					};
					ref.parent.items.push(processedItem);
				}

				myAssetsGroups.value = processedGroups;
			}
		} catch (error) {
			console.error('获取藏品列表失败:', error);
			uni.showToast({
				title: error.message || '获取藏品列表失败',
				icon: 'none',
				duration: 2000
			});
		} finally {
			modalLoading.value = false;
		}
	};
	
	// 关闭藏品选择弹窗
	const closeAssetSelectModal = () => {
		// 先触发关闭动画
		assetSelectModalAnimated.value = false;
		// 等待动画结束后再隐藏弹窗
		setTimeout(() => {
			showAssetSelectModal.value = false;
			myAssetsGroups.value = [];
			// 重置替换模式状态
			if (isReplaceMode.value) {
				isReplaceMode.value = false;
				selectedAssetForRemove.value = null;
			}
		}, 300);
	};
	
	// 处理弹窗触摸开始（仅在顶部拖动区域触发）
	const handleModalTouchStart = (e) => {
		modalTouchStartY.value = e.touches[0].clientY;
		modalTouchStartTime.value = Date.now();
	};
	
	// 处理弹窗触摸移动（仅在顶部拖动区域触发）
	const handleModalTouchMove = (e) => {
		const currentY = e.touches[0].clientY;
		const deltaY = currentY - modalTouchStartY.value;
		
		// 向下滑动时阻止默认行为，准备关闭弹窗
		if (deltaY > 0) {
			e.preventDefault();
		}
	};
	
	// 处理弹窗触摸结束（仅在顶部拖动区域触发）
	const handleModalTouchEnd = (e) => {
		const currentY = e.changedTouches[0].clientY;
		const deltaY = currentY - modalTouchStartY.value;
		const deltaTime = Date.now() - modalTouchStartTime.value;
		
		// 判断是否应该关闭弹窗
		// 条件：向下滑动距离超过100px 或 快速向下滑动（速度>0.5px/ms）
		if (deltaY > 0) {
			const velocity = deltaY / deltaTime;
			if (deltaY > 100 || velocity > 0.5) {
				closeAssetSelectModal();
			}
		}
	};
	
	// 选择藏品
	const handleAssetSelect = (asset) => {
		selectedAssetForPlace.value = asset;
		showPlaceConfirmModal.value = true;
	};
	
	// 关闭上架确认弹窗
	const closePlaceConfirmModal = () => {
		showPlaceConfirmModal.value = false;
		selectedAssetForPlace.value = null;
		// 重置替换模式状态
		if (isReplaceMode.value) {
			isReplaceMode.value = false;
			selectedAssetForRemove.value = null;
		}
	};
	
	// 确认上架藏品
	const confirmPlaceAsset = async () => {
		if (!selectedAssetForPlace.value || !selectedSlotId.value || !galleryOwnerId.value) {
			uni.showToast({
				title: '信息不完整',
				icon: 'none',
				duration: 2000
			});
			return;
		}

		try {
			// 如果是替换模式，先移除旧藏品
			if (isReplaceMode.value && selectedAssetForRemove.value && selectedAssetForRemove.value.slot_id) {
				const removeResponse = await removeAssetFromGalleryApi(selectedAssetForRemove.value.slot_id);
				if (removeResponse.code !== 200) {
					uni.showToast({
						title: removeResponse.message || '移除旧藏品失败',
						icon: 'none',
						duration: 2000
					});
					return;
				}
			}

			const response = await placeAssetToGalleryApi(
				selectedAssetForPlace.value.asset_id,
				galleryOwnerId.value,
				selectedSlotId.value
			);

			if (response.code === 200) {
				uni.showToast({
					title: isReplaceMode.value ? '替换成功' : '上架成功',
					icon: 'success',
					duration: 2000
				});

				// 关闭确认弹窗
				showPlaceConfirmModal.value = false;

				// 关闭藏品选择弹窗（带动画）
				assetSelectModalAnimated.value = false;
				setTimeout(() => {
					showAssetSelectModal.value = false;
					myAssetsGroups.value = [];
				}, 300);

				// 清空选中状态
				selectedAssetForPlace.value = null;
				selectedSlotId.value = null;
				selectedSlotIndex.value = null;

				// 重置替换模式状态
				if (isReplaceMode.value) {
					isReplaceMode.value = false;
					selectedAssetForRemove.value = null;
				}

				// 刷新展馆信息
				await loadGallerySlots();
			}
		} catch (error) {
			console.error('上架藏品失败:', error);
			uni.showToast({
				title: error.message || '上架失败，请重试',
				icon: 'none',
				duration: 2000
			});
		}
	};
	
	// 处理长按藏品
	const handleLongPress = (e, asset) => {
		// 阻止默认事件，避免触发点击
		if (e && e.preventDefault) {
			e.preventDefault();
		}

		// 检查是否为用户自己的藏品
		// 需要从本地存储获取用户uid
		const userStr = uni.getStorageSync('user');
		if (!userStr) {
			uni.showToast({
				title: '请先登录',
				icon: 'none',
				duration: 2000
			});
			return;
		}

		let currentUserUid;
		try {
			const user = JSON.parse(userStr);
			currentUserUid = user.uid;
		} catch (e) {
			console.error('解析用户信息失败:', e);
			return;
		}

		// 权限检查：根据can_operate字段判断是否可以操作
		// operation 为 'remove' 时可以替换和移除
		if (asset.operation !== 'remove') {
			uni.showToast({
				title: '该槽位不可操作',
				icon: 'none',
				duration: 2000
			});
			return;
		}

		// 检查藏品是否有occupier_uid字段
		// 如果没有，说明是用户自己的藏品（在"我的展位"中）
		// 如果有，需要比较occupier_uid和用户uid
		// 注意：在"我的展馆"中可以下架他人放置的藏品
		if (asset.occupier_uid && asset.occupier_uid !== currentUserUid && !isMyGallery.value) {
			uni.showToast({
				title: '只能操作自己的藏品',
				icon: 'none',
				duration: 2000
			});
			return;
		}

		// 检查是否有slot_id
		if (!asset.slot_id) {
			uni.showToast({
				title: '槽位信息不完整',
				icon: 'none',
				duration: 2000
			});
			return;
		}

		// 弹出操作菜单
		// 判断是否为"我的展馆"中他人放置的藏品
		const isOthersAssetInMyGallery = asset.occupier_uid && asset.occupier_uid !== currentUserUid && isMyGallery.value;

		const itemList = isOthersAssetInMyGallery
			? ['查看详情', '移除藏品']
			: ['查看详情', '替换藏品', '移除藏品'];

		uni.showActionSheet({
			itemList,
			success: (res) => {
				switch (res.tapIndex) {
					case 0: // 查看详情
						handleNftClick(asset);
						break;
					case 1: // 替换藏品 or 移除藏品
						if (isOthersAssetInMyGallery) {
							// 移除藏品
							selectedAssetForRemove.value = asset;
							showRemoveConfirmModal.value = true;
						} else {
							// 替换藏品
							handleReplaceAsset(asset);
						}
						break;
					case 2: // 移除藏品（仅自己的藏品有）
						if (!isOthersAssetInMyGallery) {
							selectedAssetForRemove.value = asset;
							showRemoveConfirmModal.value = true;
						}
						break;
				}
			}
		});
	};

	// 处理替换藏品
	const handleReplaceAsset = async (asset) => {
		// 设置为替换模式
		isReplaceMode.value = true;
		// 保存被替换的藏品信息（用于区分空槽位上架）
		selectedAssetForRemove.value = asset;

		// 设置槽位信息
		selectedSlotId.value = asset.slot_id;

		// 获取用户藏品列表
		modalLoading.value = true;
		try {
			const response = await getMyAssetsApi(1, 20);
			if (response.code === 200 && response.data && response.data.data.groups) {
				// 先展示弹窗，再异步处理图片
				showAssetSelectModal.value = true;
				setTimeout(() => {
					assetSelectModalAnimated.value = true;
				}, 50);

				// 收集所有需要处理的藏品项
				const allItems = [];
				const itemRefs = [];

				// 处理分组数据，收集 items 稍后并行处理
				const processedGroups = [];
				for (const group of response.data.data.groups) {
					const processedGroup = {
						type: group.type,
						category: group.category,
						category_name: group.category_name,
						total_count: group.total_count,
						has_more: group.has_more,
						grades: [],
						items: []
					};

					// 处理 grades
					if (group.grades) {
						for (const grade of group.grades) {
							const processedGrade = {
								grade: grade.grade,
								total_count: grade.total_count,
								has_more: grade.has_more,
								items: []
							};
							for (const item of grade.items || []) {
								allItems.push(item);
								itemRefs.push({ type: 'grade', parent: processedGrade, grade: item.grade, category: null });
							}
							processedGroup.grades.push(processedGrade);
						}
					}

					// 处理 items
					if (group.items) {
						for (const item of group.items) {
							allItems.push(item);
							itemRefs.push({ type: 'item', parent: processedGroup, grade: null, category: item.category });
						}
					}

					processedGroups.push(processedGroup);
				}

				// 并行处理所有封面URL
				const coverUrlPromises = allItems.map(item => getAssetCoverRealUrl(item.cover_url_signed));
				const coverUrls = await Promise.all(coverUrlPromises);

				// 将处理好的封面URL填回数据结构
				for (let i = 0; i < allItems.length; i++) {
					const item = allItems[i];
					const ref = itemRefs[i];
					const processedItem = {
						asset_id: item.asset_id,
						name: item.name,
						coverUrl: coverUrls[i],
						display_status: item.display_status || 0,
						like_count: item.like_count,
						grade: ref.grade,
						category: ref.category
					};
					ref.parent.items.push(processedItem);
				}

				myAssetsGroups.value = processedGroups;
			}
		} catch (error) {
			console.error('获取藏品列表失败:', error);
			uni.showToast({
				title: error.message || '获取藏品列表失败',
				icon: 'none',
				duration: 2000
			});
			// 重置状态
			isReplaceMode.value = false;
			selectedAssetForRemove.value = null;
		} finally {
			modalLoading.value = false;
		}
	};

	// 关闭下架确认弹窗
	const closeRemoveConfirmModal = () => {
		showRemoveConfirmModal.value = false;
		selectedAssetForRemove.value = null;
	};
	
	// 确认下架藏品
	const confirmRemoveAsset = async () => {
		if (!selectedAssetForRemove.value || !selectedAssetForRemove.value.slot_id) {
			uni.showToast({
				title: '槽位信息不完整',
				icon: 'none',
				duration: 2000
			});
			return;
		}
		
		try {
			uni.showLoading({
				title: '下架中...',
				mask: true
			});
			
			const response = await removeAssetFromGalleryApi(selectedAssetForRemove.value.slot_id);
			
			uni.hideLoading();
			
			if (response.code === 200) {
				uni.showToast({
					title: '下架成功',
					icon: 'success',
					duration: 1500
				});
				
				// 关闭弹窗
				closeRemoveConfirmModal();
				
				// 重新加载展馆槽位信息
				await loadGallerySlots();
			} else {
				uni.showToast({
					title: response.message || '下架失败',
					icon: 'none',
					duration: 2000
				});
			}
		} catch (error) {
			uni.hideLoading();
			console.error('下架藏品失败:', error);
			uni.showToast({
				title: error.message || '下架失败，请重试',
				icon: 'none',
				duration: 2000
			});
		}
	};
	
	// 将状态和方法暴露给页面实例，供 onBackPress 使用
	const instance = getCurrentInstance();
	if (instance) {
		instance.proxy.showAssetSelectModal = showAssetSelectModal;
		instance.proxy.closeAssetSelectModal = closeAssetSelectModal;
	}
	
	// 启动定时器
	let countdownTimer = null;
	
	// 使用 onLoad 接收页面参数
	onLoad((options) => {

		// 获取当前用户UID
		const userStr = uni.getStorageSync('user');
		if (userStr) {
			try {
				const user = JSON.parse(userStr);
				currentUserUid.value = user.uid;
			} catch (e) {
				console.error('解析用户信息失败:', e);
			}
		}

		// 如果传入了target_uid参数，则访问指定用户的展馆
		if (options && options.target_uid) {
			visitingGalleryOwnerUid.value = parseInt(options.target_uid);
			isViewingOthers.value = true;
		} else {
			// 默认访问自己的展馆
			visitingGalleryOwnerUid.value = currentUserUid.value;
			isViewingOthers.value = false;
		}

		// 处理引导跳转参数：如果传递了 guide_key，则继续该引导
		if (options && options.guide_key) {
			console.log('[Guide] exhibition 收到引导跳转参数, guide_key:', options.guide_key, 'guide_step:', options.guide_step)
			// 使用 resumeGuide 继续引导（不会检查 shouldShowGuide）
			store.dispatch('guide/resumeGuide', options.guide_key).then(res => {
				console.log('[Guide] exhibition resumeGuide 结果:', res)
			}).catch(err => {
				console.error('[Guide] exhibition resumeGuide 失败:', err)
			})
		}
	});
	
	// 处理点赞数实时更新
	const handleAssetLikeChanged = ({ asset_id, like_count }) => {
		[friendExhibitions, myExhibitions].forEach(list => {
			list.value.forEach(item => {
				if (item && item.asset_id === asset_id) {
					item.like_count = like_count;
				}
			});
		});
	};

	onMounted(() => {
		const systemInfo = uni.getSystemInfoSync();
		screenWidth.value = systemInfo.windowWidth;
		screenHeight.value = systemInfo.windowHeight;
		// 计算顶部距离
		calculateTopPadding();

		// 确保 currentUserUid 有值
		if (!currentUserUid.value) {
			const userStr = uni.getStorageSync('user');
			if (userStr) {
				try {
					const user = JSON.parse(userStr);
					currentUserUid.value = user.uid;
				} catch (e) {
					console.error('解析用户信息失败:', e);
				}
			}
		}

		// 如果 visitingGalleryOwnerUid 没有值，设置为当前用户
		if (!visitingGalleryOwnerUid.value) {
			visitingGalleryOwnerUid.value = currentUserUid.value;
			isViewingOthers.value = false;
		}

		// 加载展馆槽位信息
		loadGallerySlots();

		// 上报每日首次预览事件
		const starId = uni.getStorageSync('star_id') || 1
		reportEvent('daily_browse_asset', starId).catch(err => {
			console.error('上报预览事件失败:', err)
		})

		// 启动倒计时定时器（每秒更新一次）
		countdownTimer = setInterval(() => {
			updateCountdowns();
		}, 1000);

		// 监听点赞变化事件
		uni.$on('assetLikeChanged', handleAssetLikeChanged);

		// 延迟检查并恢复引导位置（确保 DOM 已渲染）
		setTimeout(() => {
			if (store.state.guide.isActive) {
				console.log('[Exhibition] 检测到引导激活，重新计算位置')
				store.dispatch('guide/relocateOnPageReady')
			}
		}, 500);
	});
	
	onUnmounted(() => {
		if (countdownTimer) {
			clearInterval(countdownTimer);
		}
		uni.$off('assetLikeChanged', handleAssetLikeChanged);
	});
</script>

<style scoped>

.exhibition-container {
	position: relative;
	width: 100vw;
	height: 100vh;
	min-height: 100vh;
	/* overflow-y: auto; */
	overflow: hidden;
}

.background-image {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	object-fit: cover;
	min-width: 100%;
	min-height: 100%;
}

.background-overlay {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	background: rgba(0, 0, 0, 0.3);
}

.content-wrapper {
	position: relative;
	width: 100%;
	height: 100%;
	z-index: 1;
	display: flex;
	justify-content: center;
	align-items: center;
	padding-top: 120rpx;
	box-sizing: border-box;
}

.page-title {
	font-size: 48rpx;
	color: #e6e6e6;
	font-weight: bold;
}

/* 他人展馆标题 */
.gallery-owner-title {
	position: fixed;
	top: 192rpx;
	left: 0;
	width: 100%;
	z-index: 99;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16rpx;
}

.gallery-owner-title-text {
	font-size: 36rpx;
	font-family: 'yt', sans-serif;
	color: #e6e6e6;
	text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.6);
	letter-spacing: 4rpx;
}

.view-works-btn {
	pointer-events: auto;
	background: linear-gradient(135deg, #F0E4B1 0%, #F08399 50%, #B94E73 100%);
	border-radius: 24rpx;
	padding: 12rpx 28rpx;
	box-shadow: 0 4rpx 12rpx rgba(185, 78, 115, 0.4);
}

.view-works-btn-text {
	font-size: 24rpx;
	color: #fff;
	font-weight: 600;
}

/* 展览板容器 */
.exhibition-boards {
	position: relative;
	width: 100%;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	padding-bottom: 200rpx;
	box-sizing: border-box;
}

/* 展览板 */
.exhibition-board {
	position: relative;
	width: 105%;
	display: flex;
	justify-content: center;
	
}

.exhibition-board:last-child {
	margin-bottom: 0;
}

/* 展览板图片 */
.board-image {
	width: 100%;
	display: block;
	position: relative;
	z-index: 1;
}

/* NFT卡片容器 */
.nft-cards-container {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 2;
	pointer-events: none;
}

/* 展览板标签文字 */
.board-label {
	position: absolute;
	left: 80rpx;
	bottom: 45rpx;
	font-family: 'yt', sans-serif;
	font-size: 32rpx;
	color: #e6e6e6;
	z-index: 3;
	pointer-events: none;
}

/* 展览板2右上角标签 */
.board-label-right {
	left: auto;
	right: 120rpx;
	bottom: auto;
	top: 33rpx;
	rotate: -4deg;
}

/* 藏品选择弹窗遮罩 */
.asset-select-modal-mask {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.5);
	z-index: 9998;
	display: flex;
	align-items: flex-end;
}

/* 藏品选择弹窗 */
.asset-select-modal {
	position: relative;
	width: 100%;
	height: 80vh;
	border-top-left-radius: 40rpx;
	border-top-right-radius: 40rpx;
	overflow: hidden;
	transform: translateY(100%);
	transition: transform 0.3s ease-out;
	background: #0d0820;
}

.asset-select-modal.show {
	transform: translateY(0);
}

/* 弹窗背景图片 */
.modal-background-image {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	object-fit: cover;
}

/* 弹窗内容包装器 */
.modal-content-wrapper {
	position: relative;
	z-index: 2;
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
	padding: 20rpx 30rpx 30rpx;
	box-sizing: border-box;
}

/* 顶部拖动区域 */
.modal-top-drag-area {
	flex-shrink: 0;
	width: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 0;
	cursor: grab;
}

.modal-top-drag-area:active {
	cursor: grabbing;
}

/* 拖动条 */
.modal-handle {
	width: 80rpx;
	height: 8rpx;
	background: rgba(255, 255, 255, 0.5);
	border-radius: 4rpx;
	margin: 0 auto 20rpx;
	flex-shrink: 0;
}

/* 弹窗标题 */
.modal-title {
	font-size: 36rpx;
	font-weight: bold;
	color: #e6e6e6;
	text-align: center;
	margin-bottom: 30rpx;
	margin-top: 30rpx;
	font-family: 'yt', sans-serif;
	flex-shrink: 0;
}

/* 弹窗内类型Tab */
.modal-type-tabs {
	display: flex;
	justify-content: center;
	gap: 40rpx;
	padding: 20rpx 30rpx;
	z-index: 100;
}

.modal-tab-item {
	padding: 12rpx 30rpx;
	font-size: 28rpx;
	color: rgba(255, 255, 255, 0.6);
	border-bottom: 4rpx solid transparent;
	transition: all 0.3s ease;
}

.modal-tab-item.active {
	color: #ffffff;
	border-bottom-color: #ffffff;
}

/* 弹窗内加载中 */
.modal-loading-container {
	display: flex;
	justify-content: center;
	align-items: center;
	padding-top: 200rpx;
}

.modal-loading-text {
	color: rgba(255, 255, 255, 0.6);
	font-size: 28rpx;
}

/* 弹窗内空状态 */
.modal-empty-container {
	display: flex;
	justify-content: center;
	align-items: center;
	padding-top: 200rpx;
}

.modal-empty-text {
	color: rgba(255, 255, 255, 0.6);
	font-size: 28rpx;
}

/* 弹窗内可滚动区域 */
.modal-nft-scroll-view {
	height: calc(80vh - 200rpx);
}

/* 隐藏滚动条 */
.modal-nft-scroll-view::-webkit-scrollbar {
	display: none;
}
.modal-nft-scroll-view {
	scrollbar-width: none;
	-ms-overflow-style: none;
}

/* 弹窗内藏品列表容器 */
.modal-nft-list-container {
	width: 100%;
}

/* 弹窗内藏品分组 */
.modal-nft-group {
	margin-bottom: 30rpx;
}

/* 弹窗内等级区块 */
.modal-grade-section {
	background: rgba(255, 255, 255, 0.03);
	border-radius: 16rpx;
	padding: 20rpx;
}

/* 弹窗内分组标题 */
.modal-group-header {
	margin-bottom: 16rpx;
	padding-bottom: 10rpx;
	border-bottom: 1rpx solid rgba(255, 255, 255, 0.1);
}

.modal-group-title {
	font-size: 26rpx;
	color: rgba(255, 255, 255, 0.8);
}

/* 弹窗内藏品行 - 水平滚动 */
.modal-nft-row {
	width: 100%;
	height: 288rpx;
	white-space: nowrap;
}

/* 弹窗内藏品行内容容器 */
.modal-nft-row-content {
	display: inline-block;
	white-space: nowrap;
	padding-left: 24rpx;
	height: 100%;
	width: 192rpx;
}

/* 隐藏滚动条 */
.modal-nft-row::-webkit-scrollbar {
	display: none;
}
.modal-nft-row {
	scrollbar-width: none;
	-ms-overflow-style: none;
}

/* 弹窗内藏品网格项 */
.modal-nft-grid-item {
	position: relative;
	display: inline-block;
	vertical-align: top;
	margin-right: 32rpx;
	height: 100%;
}

/* 弹窗内NFT图片 */
.modal-nft-image {
	width: 192rpx;
	height: 224rpx;
	border-radius: 16rpx;
	background: rgba(255, 255, 255, 0.05);
	display: block;
}

/* 弹窗内更多项 */
.modal-nft-grid-item.modal-more-item {
	cursor: pointer;
}

/* 弹窗内藏品信息 */
.modal-nft-info {
	padding: 12rpx 0;
	text-align: center;
}

/* 弹窗内展示状态标签 */
.modal-status-badge {
	position: absolute;
	top: 8rpx;
	right: 8rpx;
	border-radius: 8rpx;
	padding: 4rpx 8rpx;
	z-index: 1;
}
.modal-status-badge-active {
	background: linear-gradient(135deg, #FFD700, #FFA500);
	box-shadow: 0 0 12rpx rgba(255, 215, 0, 0.6);
}
.modal-status-badge-pending {
	background: rgba(0, 0, 0, 0.6);
}
.modal-status-text {
	font-size: 18rpx;
	color: #fff;
	font-weight: bold;
}

.modal-nft-name {
	display: block;
	font-size: 22rpx;
	color: rgba(255, 255, 255, 0.9);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* 弹窗内更多覆盖层 */
.modal-more-overlay {
	width: 192rpx;
	height: 224rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, 0.5);
	border-radius: 16rpx;
}

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

/* 上架确认弹窗遮罩 */
.place-confirm-modal-mask {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.5);
	z-index: 10000;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* 上架确认弹窗 */
.place-confirm-modal {
	width: 600rpx;
	background: #e6e6e6;
	border-radius: 20rpx;
	padding: 40rpx;
	z-index: 10001;
}

.confirm-title {
	font-size: 36rpx;
	font-weight: bold;
	color: #333;
	text-align: center;
	display: block;
	margin-bottom: 30rpx;
	font-family: 'yt', sans-serif;
}

.confirm-content {
	margin-bottom: 30rpx;
}

.confirm-row {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 20rpx;
}

.confirm-label {
	font-size: 28rpx;
	color: #666;
}

.confirm-value {
	font-size: 28rpx;
	color: #333;
	font-weight: bold;
}

.confirm-buttons {
	display: flex;
	justify-content: space-between;
	gap: 20rpx;
}

.confirm-btn {
	flex: 1;
	height: 80rpx;
	border-radius: 40rpx;
	font-size: 32rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	border: none;
}

.cancel-btn {
	background: #f0f0f0;
	color: #666;
}

.submit-btn {
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	color: #e6e6e6;
}

/* 底部铸爱按钮 */
.castlove-btn {
	position: fixed;
	left: 50%;
    transform: translateX(-50%);
	/* margin-top: 30rpx; */
	/* margin-bottom: 48rpx; */
	/* margin-left: auto; */
	margin-right: auto;
	min-width: 300rpx;
	max-width: 500rpx;
	width: auto;
	padding: 0 40rpx;
	height: 100rpx;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 50rpx;
	border: 4rpx solid #e6e6e6;
	font-size: 48rpx;
	font-family: 'yt', sans-serif;
	color: #e6e6e6;
	display: flex;
	align-items: center;
	justify-content: center;
	white-space: nowrap;
	z-index: 100;
	box-shadow: 
		0 0 20rpx rgba(255, 107, 157, 0.6),
		0 0 40rpx rgba(255, 140, 66, 0.4),
		0 4rpx 20rpx rgba(0, 0, 0, 0.3);
	text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
}

.castlove-btn::after {
	border: none;
}

/* 倒计时背景 */
.countdown-background {
	position: absolute;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 999rpx;
	z-index: 9;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
	opacity: 0.95;
}

/* 倒计时文字 */
.countdown-text {
	position: absolute;
	font-size: 22rpx;
	font-weight: bold;
	color: #e6e6e6;
	font-family: 'yt', sans-serif;
	text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.8);
	z-index: 10;
	/* 使用等宽数字，防止数字宽度变化导致跳动 */
	font-variant-numeric: tabular-nums;
	/* 或者使用等宽字体作为备选 */
	font-feature-settings: "tnum";
}

/* 点赞徽标（左下角） */
.like-badge {
	position: absolute;
	z-index: 11;
}

.like-icon {
	width: 36rpx;
	height: 36rpx;
	flex-shrink: 0;
	filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.45));
}

.like-count-text {
	color: #ffffff;
	font-size: 24rpx;
	font-family: 'yt', sans-serif;
	font-weight: bold;
	line-height: 1;
	text-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.85);
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum";
}

.like-count-background {
	min-width: 24rpx;
	height: 28rpx;
	padding: 0 8rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 999rpx;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
	opacity: 0.95;
}

/* 左下角角色图片 */
.character-image {
	position: fixed;
	left: 30rpx;
	bottom: 30rpx;
	width: 35%;
	max-width: 300rpx;
	z-index: 10;
	pointer-events: none;
	filter: drop-shadow(0 10rpx 20rpx rgba(0, 0, 0, 0.4));
}

/* 随机展馆左右箭头容器 */
.random-gallery-arrows {
	position: fixed;
	top: 50%;
	left: 24rpx;
	right: 24rpx;
	transform: translateY(-50%);
	display: flex;
	justify-content: space-between;
	align-items: center;
	pointer-events: none;
	z-index: 10;
}

.arrow-btn {
	width: 56rpx;
	height: 96rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 12rpx;
	pointer-events: auto;
	box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.25);
}

.arrow-btn:active {
	opacity: 0.8;
}

.arrow-text {
	font-size: 56rpx;
	color: #FFFFFF;
	font-weight: 600;
	line-height: 1;
	margin-top: -6rpx;
}
</style>
