<template>
	<view class="checkout-page">
		<view v-if="pageLoading" class="checkout-page__loading">
			<u-loading-icon mode="circle" />
		</view>

		<view v-else-if="pageError" class="checkout-page__error">
			<u-empty mode="page" :text="pageError" icon-size="80" />
			<u-button type="primary" text="重试" size="small" custom-style="margin-top:24rpx" @click="loadPreview" />
			<u-button plain text="返回" size="small" custom-style="margin-top:16rpx" @click="onBack" />
		</view>

		<template v-else-if="preview">
			<scroll-view class="checkout-scroll" scroll-y :style="{ height: scrollHeight }">
				<address-bar :address="preview.address" @click="onAddressTap" />

				<view class="shop-head">
					<image class="shop-head__avatar" :src="preview.shop.shopAvatar" mode="aspectFill" />
					<text class="shop-head__name">{{ preview.shop.shopName }}</text>
				</view>

				<view class="goods-card">
					<checkout-multi-goods-row
						v-for="item in preview.goodsList"
						:key="item.cartItemId"
						:item="item"
						@quantity-change="(qty) => onQuantityChange(item.cartItemId, qty)"
						@remark-change="(text) => onRemarkChange(item.cartItemId, text)"
					/>
				</view>

				<view class="amount-card">
					<view class="amount-row">
						<text class="amount-row__label">商品总价</text>
						<text class="amount-row__val">¥{{ preview.goodsAmountText }}</text>
					</view>
					<view class="amount-row">
						<text class="amount-row__label">运费</text>
						<view class="amount-row__right">
							<text class="amount-row__val">¥{{ preview.freightAmountText }}</text>
							<text v-if="preview.freightDesc" class="amount-row__desc">{{ preview.freightDesc }}</text>
						</view>
					</view>
				</view>

				<view class="pay-card">
					<text class="pay-card__label">支付方式</text>
					<view class="pay-card__item">
						<u-icon name="weixin-fill" color="#09bb07" size="22" />
						<text class="pay-card__text">微信支付</text>
						<u-icon name="checkbox-mark" color="#2e7d32" size="18" />
					</view>
				</view>
			</scroll-view>

			<view class="checkout-footer">
				<view class="checkout-footer__sum">
					<text class="checkout-footer__label">应付：</text>
					<text class="checkout-footer__price">¥{{ preview.payAmountText }}</text>
				</view>
				<button class="checkout-footer__btn" :disabled="submitting" @click="onSubmit">
					{{ submitting ? '提交中...' : '提交订单' }}
				</button>
			</view>
		</template>

		<u-popup :show="addressPopupShow" mode="bottom" round="16" @close="addressPopupShow = false">
			<view class="addr-popup">
				<view class="addr-popup__head">
					<text class="addr-popup__title">选择收货地址</text>
					<text class="addr-popup__add" @click="goAddAddress">新增地址</text>
				</view>
				<scroll-view scroll-y class="addr-popup__list">
					<view
						v-for="item in addressOptions"
						:key="item.addressId"
						class="addr-option"
						:class="{ 'addr-option--on': item.addressId === selectedAddressId }"
						@click="onSelectAddress(item)"
					>
						<view class="addr-option__head">
							<text class="addr-option__name">{{ item.consigneeName }}</text>
							<text class="addr-option__mobile">{{ item.mobile }}</text>
							<text v-if="item.isDefault" class="addr-option__tag">默认</text>
						</view>
						<text class="addr-option__detail">{{ item.fullAddress }}</text>
					</view>
					<view v-if="!addressOptions.length" class="addr-popup__empty">
						<text>暂无收货地址，请先新增</text>
					</view>
				</scroll-view>
			</view>
		</u-popup>

		<u-modal
			:show="payModalShow"
			title="微信支付"
			:content="payModalContent"
			show-cancel-button
			confirm-text="确认支付"
			cancel-text="取消支付"
			@confirm="onConfirmPay"
			@cancel="onCancelPay"
			@close="payModalShow = false"
		/>
	</view>
</template>

<script setup>
import { ref } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { previewCheckout, submitCheckout } from '@/api/checkout'
import { payOrder, cancelPay } from '@/api/order'
import { getAddressList } from '@/api/member'
import { mapCheckoutPreviewCart, mapAddressOption } from '@/utils/checkoutDisplay'
import {
	CHECKOUT_SOURCE_CART,
	CHECKOUT_PAY_TYPE_WECHAT,
	CART_CHECKOUT_IDS_KEY
} from '@/constants/checkout'
import { ensureApiToken } from '@/utils/apiAuth'
import { PAGE_ADDRESS_EDIT, PAGE_PAY_RESULT } from '@/utils/pageRoute'
import { useActionGuard } from '@/utils/actionGuard'
import AddressBar from '@/components/order/AddressBar.vue'
import CheckoutMultiGoodsRow from '@/components/order/CheckoutMultiGoodsRow.vue'

const submitGuard = useActionGuard()
const payGuard = useActionGuard()

const cartItemIds = ref([])
const selectedAddressId = ref(null)
const preview = ref(null)
const pageLoading = ref(true)
const pageError = ref('')
const submitting = submitGuard.locked
const previewing = ref(false)
const scrollHeight = ref('600px')

const addressPopupShow = ref(false)
const addressOptions = ref([])

const payModalShow = ref(false)
const payModalContent = ref('')
const pendingOrderId = ref(null)
const paying = payGuard.locked

let previewTimer = null

function getRemarkMap() {
	const map = {}
	;(preview.value?.goodsList || []).forEach((row) => {
		if (row.cartItemId) {
			map[row.cartItemId] = row.buyerRemark || ''
		}
	})
	return map
}

function buildLineItems() {
	return (preview.value?.goodsList || []).map((row) => ({
		cartItemId: row.cartItemId,
		goodsId: row.goodsId,
		quantity: row.quantity
	}))
}

function buildPreviewBody() {
	return {
		source: CHECKOUT_SOURCE_CART,
		addressId: selectedAddressId.value || undefined,
		cartItemIds: cartItemIds.value,
		items: buildLineItems()
	}
}

function buildSubmitBody() {
	return {
		source: CHECKOUT_SOURCE_CART,
		addressId: selectedAddressId.value,
		payType: CHECKOUT_PAY_TYPE_WECHAT,
		cartItemIds: cartItemIds.value,
		items: (preview.value?.goodsList || []).map((row) => ({
			cartItemId: row.cartItemId,
			goodsId: row.goodsId,
			quantity: row.quantity,
			buyerRemark: (row.buyerRemark || '').trim()
		}))
	}
}

function calcScrollHeight() {
	try {
		const sys = uni.getSystemInfoSync()
		scrollHeight.value = `${(sys.windowHeight || 600) - 56}px`
	} catch (e) {
		scrollHeight.value = '600px'
	}
}

async function loadPreview() {
	if (!cartItemIds.value.length || previewing.value) return
	previewing.value = true
	pageLoading.value = !preview.value
	pageError.value = ''
	try {
		const res = await previewCheckout(buildPreviewBody())
		const mapped = mapCheckoutPreviewCart(res.data, getRemarkMap())
		if (!mapped || !mapped.goodsList.length) {
			throw new Error('订单预览数据异常')
		}
		preview.value = mapped
		if (mapped.address && mapped.address.addressId) {
			selectedAddressId.value = mapped.address.addressId
		}
	} catch (e) {
		pageError.value = (e && e.msg) || (e && e.message) || '加载失败'
		if (!preview.value) {
			preview.value = null
		}
	} finally {
		pageLoading.value = false
		previewing.value = false
	}
}

function schedulePreview() {
	if (previewTimer) clearTimeout(previewTimer)
	previewTimer = setTimeout(() => {
		loadPreview()
	}, 300)
}

function onQuantityChange(cartItemId, qty) {
	const list = preview.value?.goodsList || []
	const row = list.find((item) => item.cartItemId === cartItemId)
	if (row) {
		row.quantity = qty
		schedulePreview()
	}
}

function onRemarkChange(cartItemId, text) {
	const list = preview.value?.goodsList || []
	const row = list.find((item) => item.cartItemId === cartItemId)
	if (row) {
		row.buyerRemark = text
	}
}

async function onAddressTap() {
	try {
		const res = await getAddressList()
		addressOptions.value = (res.data || []).map(mapAddressOption).filter(Boolean)
	} catch (e) {
		addressOptions.value = []
	}
	addressPopupShow.value = true
}

function onSelectAddress(item) {
	selectedAddressId.value = item.addressId
	addressPopupShow.value = false
	schedulePreview()
}

function goAddAddress() {
	addressPopupShow.value = false
	uni.navigateTo({ url: `${PAGE_ADDRESS_EDIT}?mode=add` })
}

function onSubmit() {
	submitGuard.run(async () => {
		if (!selectedAddressId.value) {
			uni.showToast({ title: '请选择收货地址', icon: 'none' })
			return
		}
		const res = await submitCheckout(buildSubmitBody())
		const data = res.data || {}
		pendingOrderId.value = data.orderId
		payModalContent.value = `订单号：${data.orderNo || '—'}\n应付金额：¥${data.payAmount != null ? data.payAmount : preview.value?.payAmountText || '—'}`
		payModalShow.value = true
	})
}

function onConfirmPay() {
	if (!pendingOrderId.value) return
	payGuard.run(async () => {
		payModalShow.value = false
		await payOrder(pendingOrderId.value)
		try {
			uni.removeStorageSync(CART_CHECKOUT_IDS_KEY)
		} catch (e) {
			// ignore
		}
		uni.redirectTo({
			url: `${PAGE_PAY_RESULT}?status=success&orderId=${pendingOrderId.value}`
		})
	})
}

function onCancelPay() {
	if (!pendingOrderId.value) return
	payGuard.run(async () => {
		payModalShow.value = false
		await cancelPay(pendingOrderId.value)
		uni.redirectTo({
			url: `${PAGE_PAY_RESULT}?status=closed&orderId=${pendingOrderId.value}`
		})
	})
}

function onBack() {
	uni.navigateBack()
}

function parseCartItemIds(options) {
	const fromQuery = (options.cartItemIds || '')
		.split(',')
		.map((id) => id.trim())
		.filter(Boolean)
	if (fromQuery.length) {
		return fromQuery
	}
	try {
		const stored = uni.getStorageSync(CART_CHECKOUT_IDS_KEY)
		if (Array.isArray(stored) && stored.length) {
			return stored.map(String)
		}
	} catch (e) {
		// ignore
	}
	return []
}

onLoad((options) => {
	calcScrollHeight()
	cartItemIds.value = parseCartItemIds(options)
	if (!cartItemIds.value.length) {
		pageError.value = '结算商品信息缺失'
		pageLoading.value = false
		setTimeout(() => onBack(), 800)
	}
})

onShow(() => {
	if (!ensureApiToken(false)) return
	if (!cartItemIds.value.length) return
	loadPreview()
})
</script>

<style lang="scss" scoped>
.checkout-page {
	min-height: 100vh;
	background: #f5f6f8;
	padding-bottom: env(safe-area-inset-bottom);
}
.checkout-page__loading,
.checkout-page__error {
	padding: 120rpx 48rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
}
.checkout-scroll {
	box-sizing: border-box;
}
.shop-head {
	display: flex;
	align-items: center;
	padding: 16rpx 24rpx;
	margin: 0 24rpx 2rpx;
	background: #fff;
	border-radius: 12rpx 12rpx 0 0;
}
.shop-head__avatar {
	width: 48rpx;
	height: 48rpx;
	border-radius: 8rpx;
	background: #eee;
}
.shop-head__name {
	margin-left: 12rpx;
	font-size: 28rpx;
	color: #333;
	font-weight: 500;
}
.goods-card {
	margin: 0 24rpx;
	background: #fff;
	border-radius: 0 0 12rpx 12rpx;
	overflow: hidden;
}
.amount-card,
.pay-card {
	margin: 16rpx 24rpx;
	padding: 24rpx;
	background: #fff;
	border-radius: 12rpx;
}
.amount-row {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	padding: 12rpx 0;
}
.amount-row__label {
	font-size: 28rpx;
	color: #666;
}
.amount-row__right {
	text-align: right;
}
.amount-row__val {
	font-size: 28rpx;
	color: #333;
}
.amount-row__desc {
	display: block;
	margin-top: 4rpx;
	font-size: 22rpx;
	color: #999;
}
.pay-card__label {
	font-size: 28rpx;
	color: #333;
	font-weight: 500;
}
.pay-card__item {
	margin-top: 16rpx;
	display: flex;
	align-items: center;
	gap: 12rpx;
}
.pay-card__text {
	flex: 1;
	font-size: 28rpx;
	color: #333;
}
.checkout-footer {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	align-items: center;
	padding: 16rpx 24rpx;
	padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
	background: #fff;
	border-top: 1rpx solid #eee;
	z-index: 10;
}
.checkout-footer__sum {
	flex: 1;
}
.checkout-footer__label {
	font-size: 26rpx;
	color: #333;
}
.checkout-footer__price {
	font-size: 36rpx;
	color: #e53935;
	font-weight: 600;
}
.checkout-footer__btn {
	min-width: 220rpx;
	height: 72rpx;
	line-height: 72rpx;
	padding: 0 32rpx;
	background: linear-gradient(135deg, #43a047 0%, #2e7d32 100%);
	color: #fff;
	font-size: 28rpx;
	border-radius: 36rpx;
	border: none;
}
.checkout-footer__btn[disabled] {
	opacity: 0.6;
}
.addr-popup {
	padding: 24rpx 24rpx calc(24rpx + env(safe-area-inset-bottom));
	max-height: 70vh;
}
.addr-popup__head {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 16rpx;
}
.addr-popup__title {
	font-size: 30rpx;
	font-weight: 600;
	color: #333;
}
.addr-popup__add {
	font-size: 26rpx;
	color: #2e7d32;
}
.addr-popup__list {
	max-height: 50vh;
}
.addr-option {
	padding: 20rpx;
	margin-bottom: 12rpx;
	background: #f9f9f9;
	border-radius: 12rpx;
	border: 2rpx solid transparent;
}
.addr-option--on {
	border-color: #2e7d32;
	background: #f1f8f2;
}
.addr-option__head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12rpx;
}
.addr-option__name {
	font-size: 28rpx;
	font-weight: 500;
	color: #333;
}
.addr-option__mobile {
	font-size: 26rpx;
	color: #666;
}
.addr-option__tag {
	font-size: 22rpx;
	color: #2e7d32;
	background: #e8f5e9;
	padding: 4rpx 10rpx;
	border-radius: 6rpx;
}
.addr-option__detail {
	display: block;
	margin-top: 8rpx;
	font-size: 24rpx;
	color: #666;
	line-height: 1.5;
}
.addr-popup__empty {
	padding: 48rpx;
	text-align: center;
	color: #999;
	font-size: 26rpx;
}
</style>
