<template>
	<div class="page dish-order-add-page">
		<div class="order-header">
			<div>
				<div class="order-room-name">{{ currentRoom.roomName || '-' }}</div>
				<div class="order-room-sub">包房号：{{ currentRoom.roomNo || '-' }}</div>
			</div>
			<el-button @click="backOrderDetail()" type="primary" icon="el-icon-back">返回订单</el-button>
		</div>

		<div class="order-main">
			<div class="dish-panel">
				<div class="dish-search">
					<el-input v-model="dishSearchName" placeholder="搜索菜品名称" clearable @keyup.enter.native="searchDish()"
						@clear="searchDish()">
						<template #append>
							<el-button icon="el-icon-search" @click="searchDish()"></el-button>
						</template>
					</el-input>
				</div>

				<div class="dish-content">
					<div class="category-list">
						<div v-for="item in categoryList" :key="item.id" class="category-item"
							:class="{ 'category-active': activeTypeId === item.id }" @click="changeType(item)">
							{{ item.name }}
						</div>
					</div>

					<div class="dish-list" v-loading="dishLoading">
						<div v-if="dishList.length === 0" class="dish-empty">暂无菜品</div>
						<div v-else class="dish-grid">
							<div v-for="item in dishList" :key="item.id" class="dish-card">
								<el-image v-if="item.previewImageUrl" class="dish-image" :src="item.previewImageUrl"
									:preview-src-list="item.previewImageList" fit="cover" hide-on-click-modal
									append-to-body :z-index="9999"></el-image>
								<div v-else class="dish-image dish-image-empty">暂无图片</div>
								<div class="dish-info">
									<div class="dish-name">{{ item.dishName }}</div>
									<div class="dish-desc">{{ item.spec || item.taste || item.remarks || '暂无说明' }}</div>
									<div class="dish-bottom">
										<span class="dish-price">￥{{ formatMoney(item.salePrice) }}</span>
										<el-button type="primary" size="small" plain @click="addDish(item)">点菜</el-button>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>

			<div class="ordered-panel" v-loading="orderLoading">
				<div class="ordered-title">本次加菜</div>
				<div v-if="orderedList.length === 0" class="ordered-empty">
					<div class="ordered-empty-title">暂未加菜</div>
					<div class="ordered-empty-sub">从左侧选择菜品后会显示在这里</div>
				</div>
				<div v-else class="ordered-list">
					<div class="ordered-head">
						<span style="text-align: center;">菜品</span>
						<span style="text-align: center;">单价</span>
						<span style="text-align: center;">总价</span>
						<span style="text-align: center;">数量</span>
					</div>
					<div>
						<div v-for="item in orderedList" :key="item.dishId" class="ordered-item">
							<div class="ordered-dish">
								<div class="ordered-dish-name">{{ item.dishName }}</div>
							</div>
							<div class="ordered-price">￥{{ formatMoney(item.salePrice) }}</div>
							<div class="ordered-total">￥{{ formatMoney(itemTotal(item)) }}</div>
							<div class="ordered-qty">
								<el-button icon="el-icon-minus" size="mini" circle @click="reduceDish(item)"></el-button>
								<span>{{ item.quantity }}</span>
								<el-button icon="el-icon-plus" size="mini" circle @click="increaseOrderedDish(item)"></el-button>
							</div>
						</div>
					</div>
				</div>
				<div class="ordered-footer">
					<div class="ordered-summary">
						<span>共 {{ orderedList.length }} 项，本次加菜金额</span>
						<strong>￥{{ formatMoney(orderTotal) }}</strong>
					</div>
					<el-button class="submit-button" type="primary" :loading="submitting" @click="confirmSubmitOrder()">下单</el-button>
				</div>
			</div>
		</div>
	</div>
</template>

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

export default {
	data() {
		return {
			currentRoom: {},
			currentOrder: null,
			categoryList: [],
			activeTypeId: 'all',
			dishSearchName: '',
			dishList: [],
			orderedList: [],
			existDishSortMap: {},
			maxDishSort: 0,
			dishLoading: false,
			orderLoading: false,
			submitting: false
		}
	},
	computed: {
		orderTotal() {
			return this.orderedList.reduce((total, item) => total + this.itemTotal(item), 0)
		},
		submitDetailList() {
			let appendIndex = 0
			return this.orderedList.map((item) => {
				let dishSort = this.existDishSortMap[item.dishId]
				if (!dishSort) {
					appendIndex += 1
					dishSort = this.maxDishSort + appendIndex
				}
				return {
					dishId: item.dishId,
					dishName: item.dishName,
					quantity: item.quantity,
					dishSort: dishSort
				}
			})
		}
	},
	dishRoomService: null,
	dishOrderService: null,
	ossService: null,
	created() {
		this.dishRoomService = new DishRoomService()
		this.dishOrderService = new DishOrderService()
		this.ossService = new OSSSerivce()
	},
	mounted() {
		this.initPage()
	},
	activated() {
		this.initPage()
	},
	methods: {
		initPage() {
			const roomId = this.$route.query.roomId
			if (!roomId) {
				this.backRoomList()
				return
			}
			this.orderedList = []
			this.activeTypeId = 'all'
			this.dishSearchName = ''
			this.loadRoom(roomId)
			this.loadCurrentOrder(roomId)
			this.loadCategoryList()
			this.loadDishList()
		},
		loadRoom(roomId) {
			this.dishRoomService.findById(roomId).then((data) => {
				this.currentRoom = data || {}
			})
		},
		loadCurrentOrder(roomId) {
			this.orderLoading = true
			this.dishOrderService.currentOrder(roomId).then((data) => {
				this.currentOrder = data || null
				if (!this.currentOrder || !this.currentOrder.id) {
					this.$message.warning('当前包房暂无未结账订单，请先下单')
					this.backOrderDetail()
					return
				}
				this.buildDishSortMap(this.currentOrder.detailList || [])
			}).finally(() => {
				this.orderLoading = false
			})
		},
		buildDishSortMap(detailList) {
			this.existDishSortMap = {}
			this.maxDishSort = 0
			detailList.forEach((item) => {
				const sort = Number(item.dishSort || 0)
				if (item.dishId && sort > 0) {
					this.existDishSortMap[item.dishId] = sort
				}
				if (sort > this.maxDishSort) {
					this.maxDishSort = sort
				}
			})
		},
		backRoomList() {
			this.$router.push({
				path: '/psiManagement/dishManage/order/DishOrder'
			})
		},
		backOrderDetail() {
			this.$router.push({
				path: '/psiManagement/dishManage/order/DishOrderDetail',
				query: {
					roomId: this.$route.query.roomId,
					refresh: Date.now()
				}
			})
		},
		loadCategoryList() {
			this.dishOrderService.typeList().then((data) => {
				this.categoryList = [
					{ id: 'all', name: '所有菜品' },
					...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 = data
				this.loadDishImagePreview()
			}).finally(() => {
				this.dishLoading = false
			})
		},
		addDish(dish) {
			const row = this.orderedList.find(item => item.dishId === dish.id)
			if (row) {
				row.quantity += 1
				return
			}
			this.orderedList.push(this.toOrderedItem(dish, 1))
		},
		increaseOrderedDish(item) {
			item.quantity += 1
		},
		reduceDish(item) {
			if (item.quantity <= 1) {
				this.orderedList = this.orderedList.filter(row => row.dishId !== item.dishId)
				return
			}
			item.quantity -= 1
		},
		confirmSubmitOrder() {
			if (this.orderedList.length === 0) {
				this.$message.warning('请先选择菜品')
				return
			}
			this.$confirm('是否确认下单？', '提示', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(() => {
				this.submitOrder()
			})
		},
		submitOrder() {
			this.submitting = true
			this.dishOrderService.submit({
				id: this.currentOrder ? this.currentOrder.id : this.$route.query.orderId,
				roomId: this.$route.query.roomId,
				settleFlag: '0',
				detailList: this.submitDetailList
			}).then((data) => {
				this.$message.success(data)
				this.backOrderDetail()
			}).finally(() => {
				this.submitting = false
			})
		},
		toOrderedItem(item, quantity) {
			return {
				dishId: item.dishId || item.id,
				dishName: item.dishName,
				salePrice: Number(item.salePrice || 0),
				quantity: quantity
			}
		},
		itemTotal(item) {
			return Number(item.salePrice || 0) * Number(item.quantity || 0)
		},
		formatMoney(value) {
			return Number(value || 0).toFixed(2)
		},
		loadDishImagePreview() {
			this.dishList.forEach((row) => {
				const urls = this.getImageUrls(row.imageUrl)
				if (urls.length === 0) {
					row.previewImageUrl = ''
					row.previewImageList = []
					return
				}
				row.previewImageList = urls
				row.previewImageUrl = urls[0]
				Promise.all(urls.map(url => this.getPreviewUrl(url))).then((list) => {
					row.previewImageList = list
					row.previewImageUrl = list[0]
				})
			})
		},
		getImageUrls(value) {
			if (!value) {
				return []
			}
			return value.split(',').map(item => item.trim()).filter(item => item)
		},
		getPreviewUrl(url) {
			if (url.indexOf('http') === 0) {
				return Promise.resolve(url)
			}
			return this.ossService.getTemporaryUrl(url).catch(() => url)
		}
	}
}
</script>

<style scoped>
.dish-order-add-page {
	display: flex;
	flex-direction: column;
}

.order-header {
	height: 64px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	border-bottom: 1px solid #ebeef5;
	padding: 0 4px 12px;
}

.order-room-name {
	font-size: 20px;
	font-weight: 600;
	color: #303133;
	line-height: 28px;
}

.order-room-sub {
	font-size: 13px;
	color: #909399;
	line-height: 20px;
}

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

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

.dish-search {
	padding: 14px;
	border-bottom: 1px solid #ebeef5;
}

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

.category-list {
	background: #f7f9fb;
	border-right: 1px solid #ebeef5;
	overflow: auto;
}

.category-item {
	min-height: 46px;
	display: flex;
	align-items: center;
	padding: 0 14px;
	cursor: pointer;
	color: #606266;
	border-left: 3px solid transparent;
}

.category-item:hover {
	color: #409eff;
	background: #eef5ff;
}

.category-active {
	color: #409eff;
	background: #fff;
	border-left-color: #409eff;
	font-weight: 600;
}

.dish-list {
	min-height: 0;
	overflow: auto;
	padding: 14px;
}

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

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

.dish-image {
	width: 100%;
	aspect-ratio: 4 / 3;
	background: #f2f3f5;
}

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

.dish-info {
	padding: 10px;
}

.dish-name {
	font-size: 15px;
	font-weight: 600;
	color: #303133;
	line-height: 22px;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.dish-desc {
	height: 24px;
	margin-top: 6px;
	color: #606266;
	font-size: 13px;
	line-height: 18px;
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

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

.dish-price {
	color: #f56c6c;
	font-size: 18px;
	font-weight: 600;
	line-height: 26px;
}

.dish-empty {
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #909399;
}

.ordered-title {
	height: 54px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 16px;
	font-size: 16px;
	font-weight: 600;
	border-bottom: 1px solid #ebeef5;
}

.ordered-empty {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	color: #909399;
	text-align: center;
	padding: 24px;
}

.ordered-empty-title {
	font-size: 16px;
	color: #606266;
	line-height: 24px;
}

.ordered-empty-sub {
	margin-top: 6px;
	font-size: 13px;
	line-height: 20px;
}

.ordered-list {
	flex: 1;
	min-height: 0;
	overflow: auto;
	padding: 12px;
}

.ordered-head,
.ordered-item {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) 72px 86px 104px;
	gap: 8px;
	align-items: center;
}

.ordered-head {
	height: 32px;
	padding: 0 8px;
	font-size: 12px;
	color: #909399;
	background: #f7f9fb;
	border-radius: 6px;
}

.ordered-item {
	min-height: 64px;
	padding: 10px 8px;
	border-bottom: 1px solid #ebeef5;
}

.ordered-dish {
	min-width: 0;
}

.ordered-dish-name {
	font-size: 14px;
	font-weight: 600;
	color: #303133;
	line-height: 20px;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.ordered-price,
.ordered-total {
	font-size: 13px;
	color: #606266;
}

.ordered-total {
	color: #f56c6c;
	font-weight: 600;
}

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

.ordered-qty span {
	min-width: 22px;
	text-align: center;
	font-weight: 600;
	color: #303133;
}

.ordered-footer {
	border-top: 1px solid #ebeef5;
	padding: 12px;
}

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

.ordered-summary strong {
	font-size: 22px;
	color: #f56c6c;
}

.submit-button {
	width: 100%;
}

@media (max-width: 1280px) {
	.order-main {
		grid-template-columns: minmax(0, 1fr) 380px;
	}

	.dish-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 960px) {
	.order-main {
		grid-template-columns: 1fr;
	}

	.dish-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.dish-content {
		grid-template-columns: 120px minmax(0, 1fr);
	}
}

@media (max-width: 640px) {
	.dish-grid {
		grid-template-columns: 1fr;
	}
}
</style>
