<template>
	<view class="dish-order-detail">
		<view class="order-header">
			<view class="room-info">
				<view class="room-name">{{ currentRoom.roomName || '-' }}</view>
				<view class="room-no">包房号：{{ currentRoom.roomNo || '-' }}</view>
			</view>
			<view class="header-actions">
				<button v-if="hasCurrentOrder" class="mini-btn success" @click="goAddDish">加菜</button>
				<button v-if="hasCurrentOrder" class="mini-btn warning" @click="openReturnDishDialog">退菜</button>
				<button class="mini-btn primary" @click="backRoomList">返回包房</button>
			</view>
		</view>

		<view class="order-main">
			<view v-if="!hasCurrentOrder" class="dish-panel">
				<view class="dish-search">
					<input class="search-input" v-model="dishSearchName" placeholder="搜索菜品名称" confirm-type="search"
						@confirm="searchDish" />
					<button class="search-btn" @click="searchDish">搜索</button>
				</view>
				<view class="dish-content">
					<scroll-view scroll-y class="category-list">
						<view v-for="item in categoryList" :key="item.id" class="category-item"
							:class="{ active: activeTypeId === item.id }" @click="changeType(item)">
							{{ item.name }}
						</view>
					</scroll-view>
					<scroll-view scroll-y class="dish-list">
						<view v-if="dishLoading" class="empty-box">加载中...</view>
						<view v-else-if="dishList.length === 0" class="empty-box">暂无菜品</view>
						<view v-else class="dish-grid">
							<view v-for="item in dishList" :key="item.id" class="dish-card">
								<image v-if="item.previewImageUrl" class="dish-image" :src="item.previewImageUrl"
									mode="aspectFill"></image>
								<view v-else class="dish-image dish-image-empty">暂无图片</view>
								<view class="dish-info">
									<view class="dish-name">{{ item.dishName }}</view>
									<view class="dish-desc">{{ item.spec || item.taste || item.remarks || '暂无说明' }}</view>
									<view class="dish-bottom">
										<text class="dish-price">￥{{ formatMoney(item.salePrice) }}</text>
										<button class="plain-btn" @click="addDish(item)">点菜</button>
									</view>
								</view>
							</view>
						</view>
					</scroll-view>
				</view>
			</view>

			<view class="ordered-panel" :class="{ full: hasCurrentOrder }">
				<view class="ordered-title">
					<text>已点菜</text>
					<view v-if="hasCurrentOrder" class="ordered-title-actions">
						<button class="text-btn" @click="openOrderInfoDialog">订单详情</button>
						<button class="text-btn danger" @click="confirmCancelOrder">取消订单</button>
					</view>
				</view>
				<scroll-view scroll-y class="ordered-list">
					<view v-if="orderLoading" class="ordered-empty">加载中...</view>
					<view v-else-if="orderedList.length === 0" class="ordered-empty">
						<view class="ordered-empty-title">暂未点菜</view>
						<view class="ordered-empty-sub">从左侧选择菜品后会显示在这里</view>
					</view>
					<view v-else>
						<view class="ordered-head">
							<text>菜品</text>
							<text>单价</text>
							<text>总价</text>
							<text>数量</text>
						</view>
						<view v-for="item in orderedList" :key="item.dishId" class="ordered-item"
							:class="{ pending: item.pendingQuantity !== 0 }">
							<view class="ordered-dish">
								<view class="ordered-dish-name">{{ item.dishName }}</view>
							</view>
							<view class="ordered-price">￥{{ formatMoney(item.salePrice) }}</view>
							<view class="ordered-total">￥{{ formatMoney(itemTotal(item)) }}</view>
							<view class="ordered-qty">
								<button v-if="!hasCurrentOrder" class="qty-btn" @click="reduceDish(item)">-</button>
								<text>{{ item.quantity }}</text>
								<button v-if="!hasCurrentOrder" class="qty-btn" @click="increaseOrderedDish(item)">+</button>
							</view>
						</view>
					</view>
				</scroll-view>
				<view class="ordered-footer">
					<view class="ordered-summary">
						<text>共 {{ orderedList.length }} 项，总价</text>
						<strong>￥{{ formatMoney(orderTotal) }}</strong>
					</view>
					<view class="ordered-actions" :class="{ one: hasCurrentOrder && !hasChangedDish }">
						<button v-if="hasCurrentOrder && !hasChangedDish" class="footer-btn success" :disabled="submitting"
							@click="openSettleDialog">结账</button>
						<button v-if="!hasCurrentOrder || hasChangedDish" class="footer-btn primary" :disabled="submitting"
							@click="confirmSubmitOrder">下单</button>
					</view>
				</view>
			</view>
		</view>

		<view v-if="settleDialogVisible" class="modal-mask">
			<view class="modal-card settle-card">
				<view class="modal-title">订单结账</view>
				<view class="settle-tabs">
					<view class="settle-tab" :class="{ active: settleForm.settleType === '0' }"
						@click="settleForm.settleType = '0'">结账</view>
					<view class="settle-tab" :class="{ active: settleForm.settleType === '1' }"
						@click="settleForm.settleType = '1'">折扣结账</view>
					<view class="settle-tab" :class="{ active: settleForm.settleType === '2' }"
						@click="settleForm.settleType = '2'">优惠结账</view>
				</view>
				<view v-if="settleForm.settleType === '0'" class="settle-normal">
					<text>订单金额</text>
					<strong>￥{{ formatMoney(orderTotal) }}</strong>
				</view>
				<view v-else class="settle-preview">
					<view>
						<text>账单原金额</text>
						<strong>￥{{ formatMoney(orderTotal) }}</strong>
					</view>
					<view v-if="settleForm.settleType === '1'">
						<text>折扣比例</text>
						<strong>{{ formatMoney(settleForm.discountRate) }}%</strong>
					</view>
					<view v-else>
						<text>优惠金额</text>
						<strong>￥{{ formatMoney(settleDiscountAmount) }}</strong>
					</view>
					<view>
						<text>应收金额</text>
						<strong class="danger-text">￥{{ formatMoney(settlePayableAmount) }}</strong>
					</view>
				</view>
				<view v-if="settleForm.settleType === '1'" class="form-row">
					<text>折扣比例</text>
					<input type="number" v-model="settleForm.discountRate" placeholder="请输入折扣比例" />
				</view>
				<view v-if="settleForm.settleType === '2'" class="form-row">
					<text>优惠金额</text>
					<input type="number" v-model="settleForm.discountAmount" placeholder="请输入优惠金额" />
				</view>
				<view class="modal-actions">
					<button class="modal-btn" @click="settleDialogVisible = false">取消</button>
					<button class="modal-btn primary" :disabled="submitting" @click="handleSettleConfirm">确认结账</button>
				</view>
			</view>
		</view>

		<view v-if="confirmOrderDialogVisible" class="modal-mask">
			<view class="modal-card">
				<view class="modal-title">确认订单</view>
				<view class="confirm-summary">
					<view><text>包间名</text><strong>{{ currentRoom.roomName || '-' }}</strong></view>
					<view><text>下单时间</text><strong>{{ confirmOrderTime || '-' }}</strong></view>
				</view>
				<view class="textarea-row">
					<text>备注</text>
					<textarea v-model="confirmOrderForm.tasteRemark" maxlength="500" placeholder="请输入备注"></textarea>
				</view>
				<view class="special-requirement-row">
					<text>特殊要求</text>
					<u-checkbox-group v-model="selectedSpecialRequirementValues" placement="column"
						@change="handleSpecialRequirementChange">
						<u-checkbox v-for="(item, index) in $dictUtils.getDictList('special_requirement')" :key="index"
							:customStyle="{ margin: '6rpx 24rpx 6rpx 0' }" :label="item.label || item.value"
							:name="String(item.value)"></u-checkbox>
					</u-checkbox-group>
				</view>
				<view class="modal-actions">
					<button class="modal-btn" @click="continueOrderDish">继续点菜</button>
					<button class="modal-btn primary" :disabled="submitting" @click="handleConfirmOrderSubmit">确认下单</button>
				</view>
			</view>
		</view>

		<view v-if="returnDishDialogVisible" class="modal-mask">
			<view class="modal-card return-card">
				<view class="modal-title">退菜</view>
				<view class="confirm-summary">
					<view><text>包房名</text><strong>{{ currentRoom.roomName || '-' }}</strong></view>
					<view><text>下单时间</text><strong>{{ currentOrder && currentOrder.createTime ? currentOrder.createTime : '-' }}</strong></view>
				</view>
				<scroll-view scroll-y class="return-list">
					<view class="return-head">
						<text>序号</text><text>菜品名</text><text>现有数量</text><text>退菜数量</text>
					</view>
					<view v-for="(item, index) in returnDishList" :key="item.dishId" class="return-row">
						<text>{{ index + 1 }}</text>
						<text class="return-name">{{ item.dishName }}</text>
						<text>{{ item.quantity }}</text>
						<input type="number" v-model="item.returnQuantity" @blur="normalizeReturnQuantity(item)" />
					</view>
				</scroll-view>
				<view class="textarea-row">
					<text>退菜原因</text>
					<textarea v-model="returnDishForm.reason" maxlength="500" placeholder="请输入退菜原因"></textarea>
				</view>
				<view class="modal-actions">
					<button class="modal-btn" @click="returnDishDialogVisible = false">取消</button>
					<button class="modal-btn primary" :disabled="submitting" @click="handleReturnDishConfirm">确认退菜</button>
				</view>
			</view>
		</view>

		<view v-if="orderInfoDialogVisible" class="modal-mask">
			<view class="modal-card info-card">
				<view class="modal-title">订单详情</view>
				<view class="info-summary">
					<view><text>订单编号</text><strong>{{ currentOrder.orderNo || '-' }}</strong></view>
					<view><text>结账方式</text><strong>{{ settleTypeName(currentOrder.settleType) }}</strong></view>
					<view><text>账单原金额</text><strong>￥{{ formatMoney(currentOrder.totalAmount) }}</strong></view>
					<view><text>实收金额</text><strong>￥{{ formatMoney(currentOrder.payableAmount) }}</strong></view>
					<view class="wide"><text>备注</text><strong>{{ currentOrder.tasteRemark || '-' }}</strong></view>
				</view>
				<view class="settle-tabs">
					<view class="settle-tab" :class="{ active: infoTab === 'actual' }" @click="infoTab = 'actual'">实际菜单</view>
					<view class="settle-tab" :class="{ active: infoTab === 'add' }" @click="infoTab = 'add'">加菜</view>
					<view class="settle-tab" :class="{ active: infoTab === 'reduce' }" @click="infoTab = 'reduce'">退菜</view>
				</view>
				<scroll-view scroll-y class="info-list">
					<view v-if="infoDetailList.length === 0" class="empty-box">暂无菜品</view>
					<view v-for="(item, index) in infoDetailList" :key="item.id || index" class="info-row">
						<view>
							<view class="info-dish-name">{{ item.dishName || '-' }}</view>
							<view class="info-dish-sub">单价 ￥{{ formatMoney(item.salePrice) }} / 数量 {{ displayQuantity(item) }}</view>
							<view v-if="infoTab === 'reduce' && item.reason" class="info-dish-sub">退菜原因：{{ item.reason }}</view>
						</view>
						<strong>￥{{ formatMoney(displayAmount(item)) }}</strong>
					</view>
				</scroll-view>
				<view class="info-total">共 {{ infoDetailList.length }} 项 / {{ infoQuantity }} 份，总价 ￥{{ formatMoney(infoAmount) }}</view>
				<view class="modal-actions">
					<button class="modal-btn primary" @click="orderInfoDialogVisible = false">关闭</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import DishOrderService from '@/api/psi/DishOrderService'
import OSSSerivce from '@/api/sys/OSSService'

export default {
	data() {
		return {
			roomId: '',
			currentRoom: {},
			currentOrder: null,
			categoryList: [],
			activeTypeId: 'all',
			dishSearchName: '',
			dishList: [],
			orderedList: [],
			dishLoading: false,
			orderLoading: false,
			submitting: false,
			settleDialogVisible: false,
			confirmOrderDialogVisible: false,
			returnDishDialogVisible: false,
			orderInfoDialogVisible: false,
			infoTab: 'actual',
			pendingOrderSubmit: null,
			confirmOrderTime: '',
			confirmOrderForm: {
				tasteRemark: ''
			},
			selectedSpecialRequirementValues: [],
			lastSpecialRequirementValues: [],
			settleForm: {
				settleType: '0',
				discountRate: 100,
				discountAmount: 0
			},
			returnDishForm: {
				reason: ''
			},
			returnDishList: [],
			dishOrderService: null,
			ossService: null
		}
	},
	computed: {
		orderTotal() {
			return this.orderedList.reduce((total, item) => total + this.itemTotal(item), 0)
		},
		orderQuantity() {
			return this.orderedList.reduce((total, item) => total + Number(item.quantity || 0), 0)
		},
		changedDetailList() {
			return this.orderedList.filter(item => item.pendingQuantity !== 0)
		},
		hasChangedDish() {
			return this.changedDetailList.length > 0
		},
		hasCurrentOrder() {
			return !!(this.currentOrder && this.currentOrder.id)
		},
		submitDetailList() {
			return this.orderedList.map((item, index) => ({
				dishId: item.dishId,
				dishName: item.dishName,
				quantity: item.pendingQuantity,
				dishSort: index + 1
			}))
		},
		settleDiscountAmount() {
			if (this.settleForm.settleType === '1') {
				return this.orderTotal - this.settlePayableAmount
			}
			if (this.settleForm.settleType === '2') {
				return Math.min(Number(this.settleForm.discountAmount || 0), this.orderTotal)
			}
			return 0
		},
		settlePayableAmount() {
			if (this.settleForm.settleType === '1') {
				const rate = Math.min(Math.max(Number(this.settleForm.discountRate || 0), 0), 100)
				return this.orderTotal * rate / 100
			}
			if (this.settleForm.settleType === '2') {
				return Math.max(this.orderTotal - Number(this.settleForm.discountAmount || 0), 0)
			}
			return this.orderTotal
		},
		infoDetailList() {
			const order = this.currentOrder || {}
			if (this.infoTab === 'add') {
				return Array.isArray(order.addDishList) ? order.addDishList : []
			}
			if (this.infoTab === 'reduce') {
				return Array.isArray(order.reduceDishList) ? order.reduceDishList : []
			}
			return Array.isArray(order.detailList) ? order.detailList : []
		},
		infoQuantity() {
			return this.infoDetailList.reduce((total, item) => total + this.displayQuantity(item), 0)
		},
		infoAmount() {
			return this.infoDetailList.reduce((total, item) => total + this.displayAmount(item), 0)
		}
	},
	onLoad(option) {
		this.roomId = option && option.roomId ? option.roomId : ''
		uni.setNavigationBarTitle({ title: '点菜' })
		this.dishOrderService = new DishOrderService()
		this.ossService = new OSSSerivce()
		this.initPage()
	},
	onShow() {
		if (this.roomId && this.dishOrderService) {
			this.loadRoom(this.roomId)
			this.loadCurrentOrder(this.roomId)
		}
	},
	methods: {
		initPage() {
			if (!this.roomId) {
				this.backRoomList()
				return
			}
			this.loadRoom(this.roomId)
			this.loadCurrentOrder(this.roomId)
			this.activeTypeId = 'all'
			this.dishSearchName = ''
			this.loadCategoryList()
			this.loadDishList()
		},
		loadRoom(roomId) {
			this.dishOrderService.findRoomById(roomId).then((data) => {
				this.currentRoom = data || {}
			})
		},
		loadCurrentOrder(roomId) {
			this.orderLoading = true
			this.dishOrderService.currentOrder(roomId).then((data) => {
				this.currentOrder = data || null
				const detailList = data && data.detailList ? data.detailList : []
				const orderedDetailList = [...detailList].sort((a, b) => Number(a.dishSort || 999999) - Number(b.dishSort || 999999))
				this.orderedList = orderedDetailList.map(item => this.toOrderedItem(item, item.quantity || 0, 0))
			}).finally(() => {
				this.orderLoading = false
			})
		},
		loadCategoryList() {
			this.dishOrderService.typeList().then((data) => {
				this.categoryList = [
					{ id: 'all', name: '所有菜品' },
					...(Array.isArray(data) ? data.map(item => ({ id: item.id, name: item.name })) : [])
				]
			})
		},
		changeType(item) {
			this.activeTypeId = item.id
			this.dishSearchName = ''
			this.loadDishList()
		},
		searchDish() {
			this.activeTypeId = 'all'
			this.loadDishList()
		},
		loadDishList() {
			this.dishLoading = true
			this.dishOrderService.dishList({
				typeId: this.activeTypeId === 'all' ? '' : this.activeTypeId,
				dishName: this.dishSearchName
			}).then((data) => {
				this.dishList = Array.isArray(data) ? data : []
				this.loadDishImagePreview()
			}).finally(() => {
				this.dishLoading = false
			})
		},
		addDish(dish) {
			const row = this.orderedList.find(item => item.dishId === dish.id)
			if (row) {
				row.quantity += 1
				row.pendingQuantity += 1
				return
			}
			this.orderedList.push(this.toOrderedItem(dish, 1, 1))
		},
		increaseOrderedDish(item) {
			item.quantity += 1
			item.pendingQuantity += 1
		},
		reduceDish(item) {
			if (item.quantity <= 0) {
				return
			}
			item.quantity -= 1
			item.pendingQuantity -= 1
			if (item.quantity === 0 && item.baseQuantity === 0) {
				this.orderedList = this.orderedList.filter(row => row.dishId !== item.dishId)
			}
		},
		openSettleDialog() {
			if (!this.hasCurrentOrder && this.changedDetailList.length === 0) {
				uni.showToast({ title: '请先选择菜品', icon: 'none' })
				return
			}
			this.settleForm = {
				settleType: '0',
				discountRate: 100,
				discountAmount: 0
			}
			this.settleDialogVisible = true
		},
		handleSettleConfirm() {
			const settleInfo = {
				settleType: this.settleForm.settleType,
				discountRate: this.settleForm.settleType === '1' ? this.settleForm.discountRate : 100,
				discountAmount: this.settleForm.settleType === '2' ? this.settleForm.discountAmount : this.settleDiscountAmount
			}
			if (!this.hasCurrentOrder) {
				this.settleDialogVisible = false
				this.openConfirmOrderDialog('1', settleInfo, false)
				return
			}
			this.submitOrder('1', settleInfo, false)
		},
		confirmSubmitOrder() {
			if (this.changedDetailList.length === 0) {
				uni.showToast({ title: '请先选择菜品', icon: 'none' })
				return
			}
			if (!this.hasCurrentOrder) {
				this.openConfirmOrderDialog('0', {}, true)
				return
			}
			uni.showModal({
				title: '提示',
				content: '是否确认下单？',
				success: (res) => {
					if (res.confirm) {
						this.submitOrder('0', {}, true)
					}
				}
			})
		},
		openConfirmOrderDialog(settleFlag, settleInfo = {}, requireChanged = false) {
			this.confirmOrderTime = this.formatDateTime(new Date())
			this.confirmOrderForm = {
				tasteRemark: ''
			}
			this.selectedSpecialRequirementValues = []
			this.lastSpecialRequirementValues = []
			this.pendingOrderSubmit = { settleFlag, settleInfo, requireChanged }
			this.confirmOrderDialogVisible = true
		},
		continueOrderDish() {
			this.confirmOrderDialogVisible = false
		},
		handleConfirmOrderSubmit() {
			const pending = this.pendingOrderSubmit || {}
			this.submitOrder(pending.settleFlag || '0', pending.settleInfo || {}, pending.requireChanged, {
				tasteRemark: this.confirmOrderForm.tasteRemark,
				specialRequirements: ''
			})
		},
		handleSpecialRequirementChange(value) {
			const current = Array.isArray(value) ? value.map(item => String(item)) : []
			const previous = this.lastSpecialRequirementValues || []
			current.filter(item => !previous.includes(item)).forEach(item => this.appendRemarkText(this.getSpecialRequirementLabel(item)))
			previous.filter(item => !current.includes(item)).forEach(item => this.removeRemarkText(this.getSpecialRequirementLabel(item)))
			this.lastSpecialRequirementValues = [...current]
		},
		getSpecialRequirementLabel(value) {
			const list = this.$dictUtils.getDictList('special_requirement') || []
			const row = list.find(item => String(item.value) === String(value))
			return row ? (row.label || row.value) : value
		},
		appendRemarkText(text) {
			if (!text) {
				return
			}
			const items = this.getRemarkItems()
			if (!items.includes(text)) {
				items.push(text)
			}
			this.confirmOrderForm.tasteRemark = items.join(',')
		},
		removeRemarkText(text) {
			if (!text) {
				return
			}
			let value = this.confirmOrderForm.tasteRemark || ''
			if (value.indexOf(`,${text}`) > -1) {
				value = value.split(`,${text}`).join('')
			} else if (value.indexOf(`${text},`) > -1) {
				value = value.split(`${text},`).join('')
			} else {
				value = value.split(text).join('')
			}
			this.confirmOrderForm.tasteRemark = this.cleanupRemarkText(value)
		},
		cleanupRemarkText(value) {
			return (value || '').split(',').map(item => item.trim()).filter(item => item).join(',')
		},
		getRemarkItems() {
			return (this.confirmOrderForm.tasteRemark || '').split(',').map(item => item.trim()).filter(item => item)
		},
		openReturnDishDialog() {
			if (!this.hasCurrentOrder) {
				return
			}
			this.returnDishForm = { reason: '' }
			this.returnDishList = this.orderedList.map(item => ({
				dishId: item.dishId,
				dishName: item.dishName,
				quantity: item.quantity,
				dishSort: item.dishSort,
				returnQuantity: 0
			}))
			this.returnDishDialogVisible = true
		},
		normalizeReturnQuantity(item) {
			let value = Number(item.returnQuantity || 0)
			value = Math.max(0, Math.min(value, Number(item.quantity || 0)))
			item.returnQuantity = Math.floor(value)
		},
		handleReturnDishConfirm() {
			const detailList = this.returnDishList
				.filter(item => Number(item.returnQuantity || 0) > 0)
				.map(item => ({
					dishId: item.dishId,
					dishName: item.dishName,
					quantity: -Number(item.returnQuantity || 0),
					dishSort: item.dishSort,
					reason: this.returnDishForm.reason
				}))
			if (detailList.length === 0) {
				uni.showToast({ title: '请填写退菜数量', icon: 'none' })
				return
			}
			this.submitting = true
			this.dishOrderService.submit({
				id: this.currentOrder.id,
				roomId: this.roomId,
				settleFlag: '0',
				detailList
			}).then((data) => {
				uni.showToast({ title: data || '退菜成功', icon: 'none' })
				this.returnDishDialogVisible = false
				this.loadRoom(this.roomId)
				this.loadCurrentOrder(this.roomId)
			}).finally(() => {
				this.submitting = false
			})
		},
		confirmCancelOrder() {
			if (!this.hasCurrentOrder) {
				uni.showToast({ title: '暂无可取消的订单', icon: 'none' })
				return
			}
			uni.showModal({
				title: '提示',
				content: '确定取消当前订单吗？取消后包房将释放。',
				success: (res) => {
					if (!res.confirm) {
						return
					}
					this.submitting = true
					this.dishOrderService.cancelOrder(this.currentOrder.id).then((data) => {
						uni.showToast({ title: data || '取消成功', icon: 'none' })
						this.backRoomList()
					}).finally(() => {
						this.submitting = false
					})
				}
			})
		},
		submitOrder(settleFlag, settleInfo = {}, requireChanged = false, orderInfo = {}) {
			const changedList = this.changedDetailList
			const detailList = settleFlag === '1' && changedList.length === 0 ? [] : this.submitDetailList
			if (requireChanged && changedList.length === 0) {
				uni.showToast({ title: '请先选择菜品', icon: 'none' })
				return
			}
			if (settleFlag === '1' && !this.hasCurrentOrder && changedList.length === 0) {
				uni.showToast({ title: '请先选择菜品', icon: 'none' })
				return
			}
			if (settleFlag !== '1' && detailList.length === 0) {
				uni.showToast({ title: '请先选择菜品', icon: 'none' })
				return
			}
			this.submitting = true
			this.dishOrderService.submit({
				id: this.hasCurrentOrder ? this.currentOrder.id : '',
				roomId: this.roomId,
				settleFlag,
				...settleInfo,
				...orderInfo,
				detailList
			}).then((data) => {
				uni.showToast({ title: data || '操作成功', icon: 'none' })
				this.settleDialogVisible = false
				this.confirmOrderDialogVisible = false
				this.loadRoom(this.roomId)
				this.loadCurrentOrder(this.roomId)
			}).finally(() => {
				this.submitting = false
			})
		},
		goAddDish() {
			if (!this.hasCurrentOrder) {
				return
			}
			uni.navigateTo({
				url: `/pages/psiManagement/dishManage/DishOrderAdd?roomId=${this.roomId}&orderId=${this.currentOrder.id}`
			})
		},
		openOrderInfoDialog() {
			this.infoTab = 'actual'
			this.orderInfoDialogVisible = true
		},
		backRoomList() {
			uni.navigateBack({
				fail: () => {
					uni.redirectTo({ url: '/pages/psiManagement/dishManage/DishOrder' })
				}
			})
		},
		toOrderedItem(item, quantity, pendingQuantity) {
			const salePrice = Number(item.salePrice || 0)
			return {
				dishId: item.dishId || item.id,
				dishName: item.dishName,
				salePrice,
				quantity,
				baseQuantity: quantity - pendingQuantity,
				pendingQuantity,
				dishSort: item.dishSort || 0
			}
		},
		itemTotal(item) {
			return Number(item.salePrice || 0) * Number(item.quantity || 0)
		},
		loadDishImagePreview() {
			this.dishList.forEach((row) => {
				const urls = this.getImageUrls(row.imageUrl)
				if (urls.length === 0) {
					this.$set ? this.$set(row, 'previewImageUrl', '') : row.previewImageUrl = ''
					this.$set ? this.$set(row, 'previewImageList', []) : row.previewImageList = []
					return
				}
				this.$set ? this.$set(row, 'previewImageUrl', urls[0]) : row.previewImageUrl = urls[0]
				this.$set ? this.$set(row, 'previewImageList', urls) : row.previewImageList = urls
				Promise.all(urls.map(url => this.getPreviewUrl(url))).then((list) => {
					row.previewImageUrl = list[0]
					row.previewImageList = list
				})
			})
		},
		getImageUrls(value) {
			if (!value) {
				return []
			}
			return value.split(',').map(item => item.trim()).filter(item => item)
		},
		getPreviewUrl(url) {
			if (!url) {
				return Promise.resolve('')
			}
			if (url.indexOf('http') === 0) {
				return Promise.resolve(url)
			}
			return this.ossService.getTemporaryUrl(url).catch(() => url)
		},
		formatMoney(value) {
			return Number(value || 0).toFixed(2)
		},
		formatDateTime(value) {
			const date = value ? new Date(value) : new Date()
			const pad = (num) => String(num).padStart(2, '0')
			return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
		},
		settleTypeName(value) {
			if (value === '1') return '折扣结账'
			if (value === '2') return '优惠结账'
			if (value === '0') return '结账'
			return '-'
		},
		displayQuantity(item) {
			return Math.abs(Number(item.quantity || 0))
		},
		displayAmount(item) {
			return Math.abs(Number(item.amount || 0))
		}
	}
}
</script>

<style scoped>
.dish-order-detail {
	height: calc(100vh - var(--window-top, 0px));
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	padding: 20rpx;
	background: #f5f6fa;
}

.order-header {
	height: 92rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 8rpx 18rpx;
	box-sizing: border-box;
	border-bottom: 1rpx solid #ebeef5;
}

.room-name {
	font-size: 34rpx;
	font-weight: 700;
	color: #303133;
	line-height: 44rpx;
}

.room-no {
	font-size: 24rpx;
	color: #909399;
	line-height: 34rpx;
}

.header-actions {
	display: flex;
	gap: 12rpx;
}

.mini-btn,
.plain-btn,
.text-btn,
.footer-btn,
.modal-btn {
	margin: 0;
	padding: 0;
	border-radius: 8rpx;
	font-size: 26rpx;
	line-height: 64rpx;
}

.mini-btn {
	width: 150rpx;
	height: 64rpx;
	color: #fff;
}

.primary,
.footer-btn.primary,
.modal-btn.primary {
	color: #fff;
	background: #2979ff;
}

.success,
.footer-btn.success {
	color: #fff;
	background: #19be6b;
}

.warning {
	color: #fff;
	background: #f9ae3d;
}

.order-main {
	flex: 1;
	min-height: 0;
	display: grid;
	grid-template-columns: minmax(0, 1fr) 720rpx;
	gap: 18rpx;
	padding-top: 18rpx;
}

.dish-panel,
.ordered-panel {
	min-height: 0;
	display: flex;
	flex-direction: column;
	border: 1rpx solid #ebeef5;
	border-radius: 10rpx;
	background: #fff;
	overflow: hidden;
}

.ordered-panel.full {
	grid-column: 1 / -1;
}

.dish-search {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 120rpx;
	gap: 12rpx;
	padding: 16rpx;
	border-bottom: 1rpx solid #ebeef5;
}

.search-input,
.form-row input,
.return-row input {
	height: 64rpx;
	box-sizing: border-box;
	padding: 0 18rpx;
	border: 1rpx solid #dcdfe6;
	border-radius: 8rpx;
	font-size: 26rpx;
	color: #303133;
}

.search-btn {
	height: 64rpx;
	margin: 0;
	padding: 0;
	border-radius: 8rpx;
	font-size: 26rpx;
	line-height: 64rpx;
	color: #fff;
	background: #2979ff;
}

.dish-content {
	flex: 1;
	min-height: 0;
	display: grid;
	grid-template-columns: 150rpx minmax(0, 1fr);
}

.category-list {
	height: 100%;
	background: #f7f9fb;
	border-right: 1rpx solid #ebeef5;
}

.category-item {
	min-height: 78rpx;
	display: flex;
	align-items: center;
	box-sizing: border-box;
	padding: 0 16rpx;
	border-left: 5rpx solid transparent;
	font-size: 26rpx;
	color: #606266;
}

.category-item.active {
	color: #2979ff;
	background: #fff;
	border-left-color: #2979ff;
	font-weight: 700;
}

.dish-list {
	height: 100%;
	box-sizing: border-box;
	padding: 16rpx;
}

.dish-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16rpx;
}

.dish-card {
	min-width: 0;
	border: 1rpx solid #ebeef5;
	border-radius: 10rpx;
	overflow: hidden;
	background: #fff;
}

.dish-image {
	width: 100%;
	height: 200rpx;
	background: #f2f3f5;
}

.dish-image-empty {
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 24rpx;
	color: #909399;
}

.dish-info {
	padding: 12rpx;
}

.dish-name,
.ordered-dish-name,
.info-dish-name {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.dish-name {
	font-size: 28rpx;
	font-weight: 700;
	color: #303133;
	line-height: 38rpx;
}

.dish-desc {
	height: 42rpx;
	margin-top: 8rpx;
	font-size: 24rpx;
	color: #606266;
	line-height: 32rpx;
	overflow: hidden;
}

.dish-bottom {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10rpx;
	margin-top: 12rpx;
}

.dish-price,
.ordered-total,
.danger-text {
	color: #fa3534;
}

.dish-price {
	font-size: 30rpx;
	font-weight: 700;
}

.plain-btn {
	width: 96rpx;
	height: 54rpx;
	line-height: 54rpx;
	color: #2979ff;
	background: #ecf5ff;
}

.ordered-title {
	height: 76rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	padding: 0 18rpx;
	border-bottom: 1rpx solid #ebeef5;
	font-size: 30rpx;
	font-weight: 700;
	color: #303133;
}

.ordered-title-actions {
	display: flex;
	gap: 10rpx;
}

.text-btn {
	width: 140rpx;
	height: 52rpx;
	line-height: 52rpx;
	color: #2979ff;
	background: #ecf5ff;
}

.text-btn.danger {
	color: #fa3534;
	background: #fff1f0;
}

.ordered-list {
	flex: 1;
	min-height: 0;
	box-sizing: border-box;
	padding: 14rpx;
}

.ordered-head,
.ordered-item {
	display: grid;
	grid-template-columns: minmax(180rpx, 1fr) 110rpx 120rpx 150rpx;
	gap: 10rpx;
	align-items: center;
	text-align: center;
}

.ordered-head {
	height: 50rpx;
	padding: 0 10rpx;
	border-radius: 8rpx;
	background: #f7f9fb;
	font-size: 24rpx;
	color: #909399;
}

.ordered-item {
	min-height: 86rpx;
	box-sizing: border-box;
	padding: 12rpx 10rpx;
	border-bottom: 1rpx solid #ebeef5;
	font-size: 24rpx;
	color: #606266;
}

.ordered-item.pending {
	background: rgba(45, 140, 240, 0.12);
}

.ordered-dish-name {
	font-size: 26rpx;
	font-weight: 700;
	color: #303133;
}

.ordered-total {
	font-weight: 700;
}

.ordered-qty {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8rpx;
}

.qty-btn {
	width: 42rpx;
	height: 42rpx;
	margin: 0;
	padding: 0;
	border-radius: 50%;
	font-size: 28rpx;
	line-height: 42rpx;
	color: #2979ff;
	background: #ecf5ff;
}

.ordered-footer {
	padding: 16rpx;
	border-top: 1rpx solid #ebeef5;
}

.ordered-summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 14rpx;
	font-size: 26rpx;
	color: #606266;
}

.ordered-summary strong {
	font-size: 36rpx;
	color: #fa3534;
}

.ordered-actions {
	display: flex;
	justify-content: flex-end;
}

.ordered-actions.one {
	justify-content: flex-end;
}

.footer-btn {
	width: 220rpx;
	height: 72rpx;
	line-height: 72rpx;
}

.ordered-empty,
.empty-box {
	min-height: 240rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	color: #909399;
	font-size: 26rpx;
}

.ordered-empty-title {
	font-size: 30rpx;
	color: #606266;
}

.ordered-empty-sub {
	margin-top: 8rpx;
	font-size: 24rpx;
}

.modal-mask {
	position: fixed;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	z-index: 999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 36rpx;
	box-sizing: border-box;
	background: rgba(0, 0, 0, 0.45);
}

.modal-card {
	width: 680rpx;
	max-height: 90vh;
	box-sizing: border-box;
	padding: 26rpx;
	border-radius: 12rpx;
	background: #fff;
	overflow: auto;
}

.settle-card {
	width: 760rpx;
}

.return-card,
.info-card {
	width: 920rpx;
}

.modal-title {
	margin-bottom: 20rpx;
	font-size: 34rpx;
	font-weight: 700;
	color: #303133;
}

.settle-tabs {
	display: flex;
	gap: 10rpx;
	margin-bottom: 18rpx;
	padding: 8rpx;
	border-radius: 10rpx;
	background: #f7f8fa;
}

.settle-tab {
	flex: 1;
	height: 58rpx;
	border-radius: 8rpx;
	text-align: center;
	font-size: 26rpx;
	line-height: 58rpx;
	color: #606266;
}

.settle-tab.active {
	color: #fff;
	background: #2979ff;
	font-weight: 700;
}

.settle-normal,
.settle-preview,
.confirm-summary,
.info-summary {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12rpx;
	margin-bottom: 18rpx;
	padding: 16rpx;
	border-radius: 8rpx;
	background: #f7f8fa;
}

.settle-normal {
	grid-template-columns: 1fr 1fr;
	align-items: center;
}

.settle-normal strong {
	text-align: right;
	font-size: 40rpx;
	color: #fa3534;
}

.settle-preview text,
.confirm-summary text,
.info-summary text {
	display: block;
	font-size: 24rpx;
	color: #909399;
	line-height: 32rpx;
}

.settle-preview strong,
.confirm-summary strong,
.info-summary strong {
	display: block;
	margin-top: 6rpx;
	font-size: 28rpx;
	color: #303133;
	line-height: 38rpx;
	word-break: break-all;
}

.info-summary {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

.info-summary .wide {
	grid-column: span 4;
}

.form-row,
.textarea-row,
.special-requirement-row {
	margin-bottom: 16rpx;
}

.form-row text,
.textarea-row text,
.special-requirement-row text {
	display: block;
	margin-bottom: 8rpx;
	font-size: 26rpx;
	color: #606266;
}

.form-row input {
	width: 100%;
}

.textarea-row textarea {
	width: 100%;
	height: 130rpx;
	box-sizing: border-box;
	padding: 14rpx;
	border: 1rpx solid #dcdfe6;
	border-radius: 8rpx;
	font-size: 26rpx;
	color: #303133;
}

.special-requirement-row u-checkbox-group {
	display: block;
	box-sizing: border-box;
	padding: 12rpx 14rpx;
	border: 1rpx solid #dcdfe6;
	border-radius: 8rpx;
}

.modal-actions {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 14rpx;
	margin-top: 18rpx;
}

.modal-btn {
	height: 72rpx;
	line-height: 72rpx;
	color: #606266;
	background: #f7f8fa;
}

.return-list,
.info-list {
	max-height: 380rpx;
}

.return-head,
.return-row {
	display: grid;
	grid-template-columns: 80rpx minmax(0, 1fr) 120rpx 140rpx;
	gap: 10rpx;
	align-items: center;
}

.return-head {
	height: 52rpx;
	padding: 0 12rpx;
	border-radius: 8rpx;
	background: #f7f9fb;
	font-size: 24rpx;
	color: #909399;
}

.return-row {
	min-height: 70rpx;
	padding: 10rpx 12rpx;
	border-bottom: 1rpx solid #ebeef5;
	font-size: 26rpx;
	color: #606266;
}

.return-name {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	font-weight: 700;
	color: #303133;
}

.info-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18rpx;
	min-height: 88rpx;
	padding: 12rpx 0;
	border-bottom: 1rpx solid #ebeef5;
}

.info-row strong {
	font-size: 28rpx;
	color: #fa3534;
}

.info-dish-name {
	font-size: 28rpx;
	font-weight: 700;
	color: #303133;
}

.info-dish-sub {
	margin-top: 6rpx;
	font-size: 24rpx;
	color: #909399;
}

.info-total {
	margin-top: 14rpx;
	text-align: right;
	font-size: 26rpx;
	color: #606266;
}
</style>
