<template>
	<view
		class="mine-drawer-stage"
		:class="{ 'mine-drawer-stage--open': open }"
	>
		<!-- 中间缝隙（强调左右两块分离） -->
		<view
			v-show="open"
			class="mine-drawer-gutter"
			:style="gutterStyle"
		/>

		<!-- 右侧设置层 -->
		<view
			class="mine-drawer-panel"
			:class="{ 'mine-drawer-panel--open': open }"
			:style="panelLayerStyle"
		>
			<slot name="drawer" />
		</view>

		<!-- 左侧点击关闭热区 -->
		<view
			v-show="open"
			class="mine-drawer-dismiss"
			:style="dismissStyle"
			@tap="onDismiss"
		>
			<view class="mine-drawer-dismiss-inner">
				<text class="mine-drawer-dismiss-icon">‹</text>
			</view>
			<text class="mine-drawer-dismiss-tip">{{ dismissTip }}</text>
		</view>

		<!-- 主内容卡片 -->
		<view
			class="mine-drawer-main"
			:class="{ 'mine-drawer-main--open': open }"
			:style="mainLayerStyle"
			@touchstart="onMainTouchStart"
			@touchmove="onMainTouchMove"
			@touchend="onMainTouchEnd"
			@touchcancel="onMainTouchEnd"
		>
			<slot />
		</view>
	</view>
</template>

<script>
const MAIN_SCALE = 0.837
const MAIN_GAP_RPX = 32
const CARD_INSET_RPX = 28
/** 左侧预览 : 右侧抽屉 = 2.5 : 7.5（占满屏宽） */
const PEEK_RATIO = 0.25
const PANEL_RATIO = 0.75
/**
 * 主屏平移：先贴到 25% 分界线，再额外左推 EXTRA，最后收回 BACK（往右）
 * 40rpx 收回 ≈ 屏宽 40/750；折算后 EXTRA 约 10%
 */
const MAIN_EXTRA_SHIFT_RATIO = 0.1
const MAIN_SHIFT_BACK_RPX = 40
const CLOSE_DRAG_THRESHOLD = 56

export default {
	name: 'MineDrawerShell',
	props: {
		open: {
			type: Boolean,
			default: false
		},
		dismissTip: {
			type: String,
			default: '返回'
		}
	},
	data() {
		return {
			winWidth: 375,
			panelWidthPx: 300,
			panelLeftPx: 94,
			gutterLeftPx: 86,
			peekWidthPx: 75,
			gapPx: 16,
			shiftBackPx: 20,
			cardInsetPx: 14,
			safeTop: 0,
			safeBottom: 0,
			dragOffset: 0,
			dragging: false,
			_touchStartX: 0,
			_touchStartY: 0,
			_touchAxis: ''
		}
	},
	computed: {
		panelLayerStyle() {
			const base = {
				paddingTop: `${this.safeTop}px`,
				paddingBottom: `${this.safeBottom}px`
			}
			if (!this.open) {
				return {
					...base,
					width: `${this.panelWidthPx}px`
				}
			}
			return {
				...base,
				left: `${this.panelLeftPx}px`,
				right: `${this.cardInsetPx}px`,
				width: 'auto',
				top: `${this.cardInsetPx}px`,
				bottom: `${this.cardInsetPx}px`,
				height: 'auto'
			}
		},
		gutterStyle() {
			return {
				left: `${this.gutterLeftPx}px`,
				width: `${this.gapPx}px`,
				top: `${this.cardInsetPx}px`,
				bottom: `${this.cardInsetPx}px`
			}
		},
		dismissStyle() {
			return { width: `${this.peekWidthPx}px` }
		},
		mainBaseShiftPx() {
			return Math.max(this.winWidth - this.peekWidthPx, 0)
		},
		mainExtraShiftPx() {
			return Math.round(this.winWidth * MAIN_EXTRA_SHIFT_RATIO)
		},
		mainTotalShiftPx() {
			const total = this.mainBaseShiftPx + this.mainExtraShiftPx - this.shiftBackPx
			return Math.max(total, 0)
		},
		mainShiftPx() {
			return this.mainTotalShiftPx
		},
		mainLayerStyle() {
			if (!this.open) return {}
			const shift = this.mainTotalShiftPx - this.dragOffset
			const style = {
				left: '0',
				right: '0',
				width: `${this.winWidth}px`,
				borderRadius: '28rpx',
				overflow: 'hidden',
				/* 必须先平移再缩放，否则 translate 在缩放坐标系里几乎不动 */
				transform: `translate3d(-${shift}px, 0, 0) scale(${MAIN_SCALE})`,
				transformOrigin: 'right center',
				top: `${this.cardInsetPx}px`,
				bottom: `${this.cardInsetPx}px`,
				height: 'auto',
				minHeight: '0'
			}
			if (this.dragging) {
				style.transition = 'none'
			}
			return style
		}
	},
	watch: {
		open(val) {
			if (!val) {
				this.dragOffset = 0
				this.dragging = false
			}
			this.togglePageScroll(val)
		}
	},
	created() {
		this.measureViewport()
		if (typeof uni.onWindowResize === 'function') {
			uni.onWindowResize(this.measureViewport)
		}
	},
	beforeDestroy() {
		if (typeof uni.offWindowResize === 'function') {
			uni.offWindowResize(this.measureViewport)
		}
		this.togglePageScroll(false)
	},
	methods: {
		measureViewport() {
			try {
				const info = uni.getSystemInfoSync()
				this.winWidth = info.windowWidth || 375
				this.safeTop = info.statusBarHeight || 0
				this.safeBottom = (info.safeAreaInsets && info.safeAreaInsets.bottom) || 0
				this.gapPx = uni.upx2px(MAIN_GAP_RPX)
				this.shiftBackPx = uni.upx2px(MAIN_SHIFT_BACK_RPX)
				this.cardInsetPx = uni.upx2px(CARD_INSET_RPX)
				this.peekWidthPx = Math.round(this.winWidth * PEEK_RATIO)
				this.panelLeftPx = this.peekWidthPx
				this.panelWidthPx = Math.round(this.winWidth * PANEL_RATIO)
				this.gutterLeftPx = Math.max(this.peekWidthPx - this.gapPx, 0)
			} catch (_) {}
		},
		onDismiss() {
			if (!this.open) return
			this.$emit('close')
		},
		onMainTouchStart(e) {
			if (!this.open || !e.touches || !e.touches.length) return
			this._touchStartX = e.touches[0].clientX
			this._touchStartY = e.touches[0].clientY
			this._touchAxis = ''
			this.dragging = false
		},
		onMainTouchMove(e) {
			if (!this.open || !e.touches || !e.touches.length) return
			const dx = e.touches[0].clientX - this._touchStartX
			const dy = e.touches[0].clientY - this._touchStartY
			if (!this._touchAxis) {
				if (Math.abs(dx) < 8 && Math.abs(dy) < 8) return
				this._touchAxis = Math.abs(dx) >= Math.abs(dy) ? 'x' : 'y'
			}
			if (this._touchAxis !== 'x') return
			if (dx <= 0) {
				this.dragOffset = 0
				return
			}
			this.dragging = true
			this.dragOffset = Math.min(dx, this.mainShiftPx)
		},
		onMainTouchEnd() {
			if (!this.open) return
			if (this.dragOffset >= CLOSE_DRAG_THRESHOLD) {
				this.$emit('close')
			}
			this.dragOffset = 0
			this.dragging = false
			this._touchAxis = ''
		},
		togglePageScroll(lock) {
			// #ifdef H5
			try {
				document.body.style.overflow = lock ? 'hidden' : ''
			} catch (_) {}
			// #endif
		}
	}
}
</script>

<style scoped>
.mine-drawer-stage {
	position: relative;
	min-height: 100vh;
	width: 100%;
	overflow-x: hidden;
	background-color: #f4f6fb;
}

.mine-drawer-stage--open {
	position: fixed;
	left: 0;
	top: 0;
	right: 0;
	bottom: 0;
	z-index: 10050;
	overflow: hidden;
	background-color: #d8dee8;
}

.mine-drawer-gutter {
	position: fixed;
	z-index: 4;
	pointer-events: none;
	border-radius: 8rpx;
	background-color: #d8dee8;
}

.mine-drawer-panel {
	position: fixed;
	top: 0;
	right: 0;
	height: 100vh;
	z-index: 2;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	background: #f6f8fc;
	transform: translateX(100%);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: transform 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		opacity 0.32s ease,
		visibility 0.42s,
		top 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		bottom 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		right 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		border-radius 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		box-shadow 0.42s cubic-bezier(0.32, 0.72, 0, 1);
	will-change: transform, opacity;
}

.mine-drawer-panel--open {
	z-index: 7;
	transform: translateX(0);
	opacity: 1;
	visibility: visible;
	pointer-events: all;
	border-radius: 28rpx;
	border: 2rpx solid #ffffff;
	overflow: hidden;
	box-shadow: 0 12rpx 48rpx rgba(15, 23, 42, 0.12);
}

.mine-drawer-dismiss {
	position: fixed;
	left: 0;
	top: 0;
	height: 100vh;
	z-index: 6;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.mine-drawer-dismiss-inner {
	width: 72rpx;
	height: 72rpx;
	border-radius: 50%;
	background: #ffffff;
	border: 1rpx solid #e5e7eb;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 6rpx 20rpx rgba(15, 23, 42, 0.08);
}

.mine-drawer-dismiss-icon {
	font-size: 44rpx;
	color: #4b5563;
	line-height: 1;
	font-weight: 300;
	margin-right: 4rpx;
}

.mine-drawer-dismiss-tip {
	margin-top: 16rpx;
	font-size: 22rpx;
	color: #6b7280;
	letter-spacing: 2rpx;
}

.mine-drawer-main {
	position: relative;
	z-index: 3;
	min-height: 100vh;
	width: 100%;
	background-color: #f4f6fb;
	transition: transform 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		border-radius 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		box-shadow 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		top 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		bottom 0.42s cubic-bezier(0.32, 0.72, 0, 1),
		height 0.42s cubic-bezier(0.32, 0.72, 0, 1);
	transform-origin: 100% 50%;
	will-change: transform;
}

.mine-drawer-main--open {
	position: fixed;
	left: 0;
	right: 0;
	z-index: 4;
	border-radius: 28rpx;
	border: 2rpx solid #ffffff;
	overflow: hidden;
	box-shadow: 0 12rpx 48rpx rgba(15, 23, 42, 0.14);
}
</style>
