<template>
	<!-- 右键列表 -->
	<transition name="fade">
		<!-- 在某个文件上右键 -->
		<ul
			class="right-menu-list"
			id="rightMenuList"
			v-show="visible"
			v-if="selectedFile !== undefined"
			:style="`top: ${rightMenu.top};right: ${rightMenu.right};bottom: ${rightMenu.bottom};left: ${rightMenu.left};`"
		>
			<li class="right-menu-item" @click="$file.handleFileNameClick(selectedFile, 0, [selectedFile])" v-if="seeBtnShow">
				<eye-outlined /> 查看
			</li>
			<li class="right-menu-item" @click="handleDeleteFileBtnClick(selectedFile)" v-if="deleteBtnShow">
				<delete-outlined /> 删除
			</li>
			<li class="right-menu-item" @click="handleRestoreFileBtnClick(selectedFile)" v-if="restoreBtnShow">
				<rollback-outlined /> 还原
			</li>
			<li class="right-menu-item" @click="handleCopyFileBtnClick(selectedFile)" v-if="copyBtnShow">
				<copy-outlined /> 复制到
			</li>
			<li class="right-menu-item" @click="handleMoveFileBtnClick(selectedFile)" v-if="moveBtnShow">
				<export-outlined /> 移动
			</li>
			<li class="right-menu-item" @click="handleRenameFileBtnClick(selectedFile)" v-if="renameBtnShow">
				<edit-outlined /> 重命名
			</li>
			<li class="right-menu-item" @click="handleShareFileBtnClick(selectedFile)" v-if="shareBtnShow">
				<share-alt-outlined /> 分享
			</li>
			<li class="right-menu-item" @click="visible = false" v-if="downloadBtnShow">
				<a
					target="_blank"
					style="display: block; color: inherit"
					:href="$file.getDownloadFilePath(selectedFile)"
					:download="selectedFile.fileName + '.' + selectedFile.extendName"
				>
					<download-outlined /> 下载
				</a>
			</li>
			<!-- 0-解压到当前文件夹， 1-自动创建该文件名目录，并解压到目录里， 3-手动选择解压目录 -->
			<li class="right-menu-item unzip-menu-item" v-if="unzipBtnShow">
				<folder-outlined /> 解压缩
				<right-outlined />
				<ul
					class="unzip-list"
					:style="`top: ${unzipMenu.top};bottom: ${unzipMenu.bottom};left: ${unzipMenu.left};right: ${unzipMenu.right};`"
				>
					<li class="unzip-item" @click="handleUnzipFileBtnClick(selectedFile, 0)">
						<folder-outlined /> 解压到当前文件夹
					</li>
					<li
						class="unzip-item"
						@click="handleUnzipFileBtnClick(selectedFile, 1)"
						:title="`解压到&quot;${selectedFile.fileName}&quot;`"
					>
						<folder-outlined /> 解压到"{{ selectedFile.fileName }}"
					</li>
					<li class="unzip-item" @click="handleUnzipFileBtnClick(selectedFile, 2)">
						<folder-outlined /> 解压到目标文件夹
					</li>
				</ul>
			</li>
			<!-- <li
				class="right-menu-item"
				@click="handleClickFolderEdit"
				v-if="folderEditBtnShow"
			>
				<edit-outlined /> 编辑文件夹
			</li> -->
			<!-- <li class="right-menu-item" @click="handleClickFileEdit(selectedFile)" v-if="onlineEditBtnShow">
				<edit-outlined /> 在线编辑
			</li> -->
			<li
				class="right-menu-item"
				@click="$file.copyShareLink(selectedFile.shareBatchNum, selectedFile.extractionCode)"
				v-if="copyLinkBtnShow"
			>
				<edit-outlined /> 复制链接
			</li>
			<li class="right-menu-item" @click="handleShowDetailInfo(selectedFile)" v-if="detailInfoBtnShow">
				<file-outlined /> 文件详情
			</li>
		</ul>
		<!-- 在空白处右键，右键列表展示新建文件夹、新建文件等操作按钮 -->
		<ul
			class="right-menu-list add"
			id="rightMenuList"
			v-show="visible"
			v-else
			:style="`top: ${rightMenu.top};right: ${rightMenu.right};bottom: ${rightMenu.bottom};left: ${rightMenu.left};`"
		>
			<li class="right-menu-item" @click="callback('confirm')"><reload-outlined /> 刷新</li>
			<template v-if="fileType === 0">
				<a-divider />
				<li class="right-menu-item" @click="handleClickAddFolderBtn"><folder-add-outlined /> 新建文件夹</li>
				<!-- <li class="right-menu-item" @click="handleCreateFile('docx')"><img :src="wordImg" />新建 Word 文档</li>
				<li class="right-menu-item" @click="handleCreateFile('xlsx')"><img :src="excelImg" />新建 Excel 工作表</li>
				<li class="right-menu-item" @click="handleCreateFile('pptx')"><img :src="pptImg" />新建 PPT 演示文稿</li> -->
				<a-divider />
				<li class="right-menu-item" @click="handleUploadFileBtnClick(1)"><upload-outlined /> 上传文件</li>
				<li class="right-menu-item" @click="handleUploadFileBtnClick(2)"><folder-open-outlined /> 上传文件夹</li>
				<li class="right-menu-item" @click="handleUploadFileBtnClick(3)"><drag-outlined /> 拖拽上传</li>
			</template>
		</ul>
	</transition>
</template>

<script setup>
	import { ref, computed, watch, getCurrentInstance } from 'vue'
	import { useRouter } from 'vue-router'
	import { useMyResourceStore } from '@/store/myResource.js'
	import {
		EyeOutlined,
		DeleteOutlined,
		RollbackOutlined,
		CopyOutlined,
		ExportOutlined,
		EditOutlined,
		ShareAltOutlined,
		DownloadOutlined,
		FolderOutlined,
		RightOutlined,
		FileOutlined,
		ReloadOutlined,
		FolderAddOutlined,
		UploadOutlined,
		FolderOpenOutlined,
		DragOutlined
	} from '@ant-design/icons-vue'
	import { officeFileType, fileSuffixCodeModeMap, markdownFileType } from '@/libs/map.js'
	// 导入图片资源
	import dirImgSrc from '@/assets/images/myResource/file/dir.png'
	import wordImgSrc from '@/assets/images/myResource/file/file_word.svg'
	import excelImgSrc from '@/assets/images/myResource/file/file_excel.svg'
	import pptImgSrc from '@/assets/images/myResource/file/file_ppt.svg'

	const router = useRouter()
	const myResourceStore = useMyResourceStore()

	// 定义props
	const props = defineProps({
		selectedFile: Object,
		domEvent: Object,
		serviceEl: Object,
		callback: Function
	})

	// 响应式数据
	const visible = ref(false) // 右键菜单是否显示
	const sortedFileList = ref([]) // 排序后的表格数据
	const { proxy } = getCurrentInstance()
	// 右键菜单位置
	const rightMenu = ref({
		top: 0,
		left: 0,
		bottom: 'auto',
		right: 'auto'
	})

	// 右键解压缩菜单位置
	const unzipMenu = ref({
		top: 0,
		bottom: 'auto',
		left: '126px',
		right: 'auto'
	})

	// 图片资源 - 使用导入的图片资源
	const dirImg = ref(dirImgSrc)
	const wordImg = ref(wordImgSrc)
	const excelImg = ref(excelImgSrc)
	const pptImg = ref(pptImgSrc)

	// 计算属性
	// 路由名称
	const routeName = computed(() => {
		return router.currentRoute.value.name
	})

	// 左侧菜单选中的文件类型
	const fileType = computed(() => {
		return router.currentRoute.value.query.fileType ? Number(router.currentRoute.value.query.fileType) : 0
	})

	// 当前路径
	const filePath = computed(() => {
		return router.currentRoute.value.query.filePath
	})

	// 查看按钮是否显示
	const seeBtnShow = computed(() => {
		return fileType.value !== 6
	})

	// 删除按钮是否显示
	const deleteBtnShow = computed(() => {
		return fileType.value !== 8 && !['Share'].includes(routeName.value)
	})

	// 还原按钮是否显示
	const restoreBtnShow = computed(() => {
		return fileType.value === 6 && !['Share'].includes(routeName.value)
	})

	// 复制按钮是否显示
	const copyBtnShow = computed(() => {
		return ![6, 8].includes(fileType.value) && !['Share'].includes(routeName.value)
	})

	// 移动按钮是否显示
	const moveBtnShow = computed(() => {
		return ![6, 8].includes(fileType.value) && !['Share'].includes(routeName.value)
	})

	// 重命名按钮是否显示
	const renameBtnShow = computed(() => {
		return ![6, 8].includes(fileType.value) && !['Share'].includes(routeName.value)
	})

	// 分享按钮是否显示
	const shareBtnShow = computed(() => {
		return ![6, 8].includes(fileType.value) && !['Share'].includes(routeName.value)
	})

	// 下载按钮是否显示
	const downloadBtnShow = computed(() => {
		return ![6, 8].includes(fileType.value)
	})

	// 解压缩按钮是否显示
	const unzipBtnShow = computed(() => {
		return (
			![6, 8].includes(fileType.value) &&
			!['Share'].includes(routeName.value) &&
			['zip', 'rar', '7z', 'tar', 'gz'].includes(props.selectedFile.extendName)
		)
	})

	// 编辑文件夹按钮是否显示
	const folderEditBtnShow = computed(() => {
		return ![6, 8].includes(fileType.value) && props.selectedFile.isDir === 1 && !['Share'].includes(routeName.value)
	})

	// 在线编辑按钮是否显示
	const onlineEditBtnShow = computed(() => {
		return (
			![6, 8].includes(fileType.value) &&
			(officeFileType.includes(props.selectedFile.extendName) ||
				markdownFileType.includes(props.selectedFile.extendName) ||
				fileSuffixCodeModeMap.has(props.selectedFile.extendName)) &&
			!['Share'].includes(routeName.value)
		)
	})

	// 复制链接按钮是否显示
	const copyLinkBtnShow = computed(() => {
		return fileType.value === 8
	})

	// 文件详情按钮是否显示
	const detailInfoBtnShow = computed(() => {
		return true
	})

	// 上传文件组件参数
	const uploadFileParams = computed(() => {
		return {
			filePath: filePath.value,
			isDir: 0
		}
	})

	// 监听右键列表状态
	watch(visible, (newValue) => {
		if (newValue === true) {
			document.body.addEventListener('click', closeRightMenu)
			handleOpenContextMenu()
		} else {
			document.body.removeEventListener('click', closeRightMenu)
		}
	})

	// 方法
	/**
	 * 打开右键菜单
	 */
	const handleOpenContextMenu = () => {
		// 纵坐标设置
		if (
			document.body.clientHeight - props.domEvent.clientY <
			document.querySelectorAll('#rightMenuList > .right-menu-item').length * 36 + 10
		) {
			// 如果到底部的距离小于元素总高度
			rightMenu.value.top = 'auto'
			rightMenu.value.bottom = `${document.body.clientHeight - props.domEvent.clientY}px`
			unzipMenu.value.top = 'auto'
			unzipMenu.value.bottom = '0px'
		} else {
			rightMenu.value.top = `${props.domEvent.clientY}px`
			rightMenu.value.bottom = 'auto'
			unzipMenu.value.top = '0px'
			unzipMenu.value.bottom = 'auto'
		}
		// 横坐标设置
		if (document.body.clientWidth - props.domEvent.clientX < 138) {
			// 如果到右边的距离小于元素总宽度
			rightMenu.value.left = 'auto'
			rightMenu.value.right = `${document.body.clientWidth - props.domEvent.clientX}px`
			unzipMenu.value.left = '-200px'
			unzipMenu.value.right = 'auto'
		} else {
			rightMenu.value.left = `${props.domEvent.clientX + 8}px`
			rightMenu.value.right = 'auto'
			unzipMenu.value.left = '126px'
			unzipMenu.value.right = 'auto'
		}
		visible.value = true
	}

	/**
	 * 关闭右键列表
	 */
	const closeRightMenu = (event) => {
		// 使用 classList.contains 方法替代 className.includes
		const target = event.target
		const hasOperateMoreClass =
			target.classList.contains('operate-more-') ||
			(typeof target.className === 'string' && target.className.includes('operate-more-'))
		const hasUnzipMenuItemClass =
			target.classList.contains('unzip-menu-item') ||
			(typeof target.className === 'string' && target.className.includes('unzip-menu-item'))

		if (!hasOperateMoreClass && !hasUnzipMenuItemClass) {
			visible.value = false
			if (props.selectedFile !== undefined) {
				// 不是在空白处右键时
				props.callback('cancel')
			}
		}
	}

	/**
	 * 复制按钮点击事件
	 * @description 向父组件传递当前操作的文件信息，并打开"复制文件对话框"
	 * @param {object} fileInfo 文件信息
	 */
	const handleCopyFileBtnClick = (fileInfo) => {
		visible.value = false
		proxy.$openDialog
			.copyFile({
				fileInfo
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 移动按钮点击事件
	 * @description 向父组件传递当前操作的文件信息，并打开"移动文件对话框"
	 * @param {object} fileInfo 文件信息
	 */
	const handleMoveFileBtnClick = (fileInfo) => {
		visible.value = false
		proxy.$openDialog
			.moveFile({
				isBatchOperation: false,
				fileInfo
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 解压缩按钮点击事件
	 * @description 调用解压缩文件接口，并展示新的文件列表
	 * @param {object} fileInfo 文件信息
	 * @param {number} unzipMode 解压模式 0-解压到当前文件夹， 1-自动创建该文件名目录，并解压到目录里， 2-手动选择解压目录
	 */
	const handleUnzipFileBtnClick = (fileInfo, unzipMode) => {
		visible.value = false
		proxy.$openDialog
			.unzipFile({
				unzipMode: unzipMode,
				userFileId: fileInfo.userFileId
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 删除按钮点击事件
	 * @description 区分 删除到回收站中 | 在回收站中彻底删除，打开确认对话框
	 * @param {object} fileInfo 文件信息
	 */
	const handleDeleteFileBtnClick = (fileInfo) => {
		visible.value = false
		proxy.$openDialog
			.deleteFile({
				isBatchOperation: false,
				fileInfo,
				deleteMode: fileType.value === 6 ? 2 : 1 //  删除类型：1-删除到回收站 2-彻底删除
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 还原按钮点击事件
	 * @description 调用接口，在回收站中还原文件
	 * @param {object} fileInfo 文件信息
	 */
	const handleRestoreFileBtnClick = (fileInfo) => {
		visible.value = false
		proxy.$openDialog
			.restoreFile({
				deleteBatchNum: fileInfo.deleteBatchNum,
				filePath: fileInfo.filePath
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 文件重命名按钮点击事件
	 * @description 打开确认对话框让用户输入新的文件名
	 * @param {object} fileInfo 文件信息
	 */
	const handleRenameFileBtnClick = (fileInfo) => {
		visible.value = false
		proxy.$openDialog
			.renameFile({
				oldFileName: fileInfo.fileName,
				userFileId: fileInfo.userFileId
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 文件分享按钮点击事件
	 * @description 打开对话框让用户选择过期时间和提取码
	 * @param {object} fileInfo 文件信息
	 */
	const handleShareFileBtnClick = (fileInfo) => {
		visible.value = false
		proxy.$openDialog.shareFile({
			fileInfo: [
				{
					userFileId: fileInfo.userFileId
				}
			]
		})
	}

	/**
	 * 编辑文件夹按钮点击事件
	 */
	const handleClickFolderEdit = () => {
		router.push({
			name: 'WebIDE',
			query: { filePath: props.selectedFile.filePath }
		})
	}

	/**
	 * 文件在线编辑按钮点击事件
	 * @description 打开 代码预览对话框 或 office 编辑页面
	 * @param {object} fileInfo 文件信息
	 */
	const handleClickFileEdit = (fileInfo) => {
		if (officeFileType.includes(fileInfo.extendName)) {
			// office 编辑页面
			// proxy.$file.getFileOnlineEditPathByOffice(fileInfo)
		} else if (markdownFileType.includes(fileInfo.extendName)) {
			// markdown 编辑浮层
			proxy.$openBox.markdownPreview({
				fileInfo: fileInfo,
				editable: true
			})
		} else {
			// 代码编辑对话框
			proxy.$openBox.codePreview({ fileInfo: fileInfo, isEdit: true })
		}
	}

	/**
	 * 文件详情按钮点击事件
	 * @description 打开对话框展示文件完整信息
	 * @param {object} fileInfo 文件信息
	 */
	const handleShowDetailInfo = (fileInfo) => {
		visible.value = false
		proxy.$openDialog.showFileDetail({ fileInfo })
	}

	/**
	 * 新建文件夹按钮点击事件
	 * @description 调用新建文件夹服务，并在弹窗确认回调事件中刷新文件列表
	 */
	const handleClickAddFolderBtn = () => {
		proxy.$openDialog
			.addFolder({
				filePath: router.currentRoute.value.query.filePath || '/'
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 新建 office 文件
	 * @description 调用新建 office 文件服务，并在弹窗确认回调事件中刷新文件列表
	 * @param {string} 文件扩展名 docx xlsx pptx
	 */
	const handleCreateFile = (extendName) => {
		proxy.$openDialog
			.addFile({
				extendName: extendName
			})
			.then((res) => {
				props.callback(res)
			})
	}

	/**
	 * 上传文件按钮点击事件
	 * @description 通过Bus通信，开启全局上传文件流程
	 * @param {boolean} uploadWay 上传方式 0-文件上传 1-文件夹上传 2-粘贴图片或拖拽上传
	 */
	const handleUploadFileBtnClick = (uploadWay) => {
		proxy.$openBox.uploadFile({
			params: uploadFileParams.value,
			uploadWay,
			serviceEl: props.serviceEl,
			callType: true //  callType 调用此服务的方式：1 - 顶部栏，2 - 右键菜单
		})
	}

	// 暴露方法给父组件
	defineExpose({
		visible,
		handleOpenContextMenu
	})
</script>

<style lang="less" scoped>
	@import '@/style/myResource/varibles.less';
	@import '@/style/myResource/mixins.less';

	.right-menu-list {
		position: fixed;
		display: flex;
		flex-direction: column;
		background: #fff;
		border: 1px solid @border-color-light;
		border-radius: 4px;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
		z-index: 2;
		padding: 4px 0;
		color: @regular-text;
		list-style: none;

		.right-menu-item,
		.unzip-item {
			padding: 0 16px;
			height: 36px;
			line-height: 36px;
			cursor: pointer;
			&:hover {
				background: @primary-hover;
				color: @Primary;
			}
			i {
				margin-right: 8px;
			}
		}

		&.add {
			.right-menu-item {
				display: flex;
				align-items: center;
				img {
					margin-right: 4px;
					height: 20px;
				}
				i {
					margin-right: 4px;
					font-size: 18px;
				}
			}
		}

		.unzip-menu-item {
			position: relative;
			&:hover {
				.unzip-list {
					display: block;
				}
			}
			.unzip-list {
				position: absolute;
				display: none;
				list-style: none;
				.unzip-item {
					width: 200px;
					.setEllipsis(1);
				}
			}
		}
	}
	.right-menu-list,
	.unzip-list {
		background: #fff;
		border: 1px solid @border-color-light;
		border-radius: 6px;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
		z-index: 2;
		padding: 8px 0;
		color: @regular-text;
		font-size: 14px;
		.a-divider {
			margin: 2px 0;
		}
	}
</style>
