<template>
	<el-dialog :title="dialogTitle" :close-on-click-modal="false" top="5vh" width="1100px" v-model="visible">
		<div v-loading="loading">
			<TreeTransfer v-model="selectedDishIds" :data="dishTreeData" :titles="transferTitles" height="480px">
			</TreeTransfer>
		</div>
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="visible = false" icon="el-icon-circle-close">取消</el-button>
				<el-button type="primary" :loading="submitting" @click="submit()"
					icon="el-icon-circle-check">确定</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script>
import TreeTransfer from '@/components/treeTransfer/TreeTransfer'
import DishMenuService from '@/api/psi/DishMenuService'
import DishLibraryService from '@/api/psi/DishLibraryService'
import DishTypeService from '@/api/psi/DishTypeService'

export default {
	components: {
		TreeTransfer
	},
	emits: ['refreshList'],
	data() {
		return {
			visible: false,
			loading: false,
			submitting: false,
			mode: 'add',
			dishTreeData: [],
			selectedDishIds: []
		}
	},
	computed: {
		dialogTitle() {
			return this.mode === 'update' ? '更新菜单' : '添加菜品'
		},
		transferTitles() {
			return this.mode === 'update' ? ['菜品库', '更新后菜单'] : ['可添加菜品', '已选菜品']
		}
	},
	dishMenuService: null,
	dishLibraryService: null,
	dishTypeService: null,
	created() {
		this.dishMenuService = new DishMenuService()
		this.dishLibraryService = new DishLibraryService()
		this.dishTypeService = new DishTypeService()
	},
	methods: {
		init(mode = 'add') {
			this.mode = mode
			this.visible = true
			this.loading = true
			this.submitting = false
			this.dishTreeData = []
			this.selectedDishIds = []
			Promise.all([
				this.dishTypeService.list({}),
				this.dishLibraryService.list({
					current: 1,
					size: 1000000
				}),
				this.dishMenuService.list({
					current: 1,
					size: 1000000
				})
			]).then(([typeList, dishPage, currentMenuPage]) => {
				const dishList = dishPage && dishPage.records ? dishPage.records : []
				const currentMenuList = currentMenuPage && currentMenuPage.records ? currentMenuPage.records : []
				const currentDishIds = currentMenuList.map(item => item.dishId)
				const currentDishIdSet = new Set(currentDishIds)
				const selectableDishList = dishList.filter(item => item.status === '0' || currentDishIdSet.has(item.id))

				this.dishTreeData = this.buildDishTree(typeList || [], selectableDishList)
				this.selectedDishIds = currentDishIds.filter(id => selectableDishList.some(item => item.id === id))
				this.loading = false
			}).catch(() => {
				this.loading = false
			})
		},
		buildDishTree(typeList, dishList) {
			const typeNodeMap = new Map()
			typeList.forEach(item => {
				typeNodeMap.set(item.id, {
					id: `type:${item.id}`,
					typeId: item.id,
					parentId: item.parentId,
					label: item.name,
					isLeaf: false,
					children: []
				})
			})

			const rootNodes = []
			typeNodeMap.forEach(node => {
				const parent = typeNodeMap.get(node.parentId)
				if (parent) {
					parent.children.push(node)
				} else {
					rootNodes.push(node)
				}
			})

			const uncategorizedDishes = []
			dishList.forEach(item => {
				const dishNode = {
					id: item.id,
					label: item.dishName,
					isLeaf: true
				}
				const typeNode = typeNodeMap.get(item.typeId)
				if (typeNode) {
					typeNode.children.push(dishNode)
				} else {
					uncategorizedDishes.push(dishNode)
				}
			})

			const result = this.pruneEmptyTypes(rootNodes)
			if (uncategorizedDishes.length > 0) {
				result.push({
					id: 'type:uncategorized',
					label: '未分类',
					isLeaf: false,
					children: uncategorizedDishes
				})
			}
			return result
		},
		pruneEmptyTypes(nodes) {
			return nodes.reduce((result, node) => {
				const typeChildren = node.children.filter(item => item.isLeaf !== true)
				const dishChildren = node.children.filter(item => item.isLeaf === true)
				const children = [...this.pruneEmptyTypes(typeChildren), ...dishChildren]
				if (children.length > 0) {
					result.push({
						...node,
						children
					})
				}
				return result
			}, [])
		},
		submit() {
			if (this.mode === 'update' && this.selectedDishIds.length === 0) {
				this.$message.warning('请至少保留一道菜品')
				return
			}
			this.submitting = true
			const request = this.mode === 'update'
				? this.dishMenuService.updateMenu(this.selectedDishIds)
				: this.dishMenuService.saveDishes(this.selectedDishIds)
			request.then((data) => {
				this.$message.success(data)
				this.visible = false
				this.$emit('refreshList')
			}).finally(() => {
				this.submitting = false
			})
		}
	}
}
</script>
