<template>
	<transition name="fade">
		<div class="markdown-preview-wrapper" v-show="visible" @click.self="closeMarkdownPreview">
			<!-- 顶部信息栏 & 工具栏 -->
			<div class="tip-wrapper" v-if="visible">
				<div class="name" :title="getFileNameComplete(fileInfo)">
					{{ getFileNameComplete(fileInfo) }}
					<span class="un-save" v-show="isModify">（未保存）</span>
				</div>
				<div class="editor-preveiw">在线预览{{ editable ? ' & 编辑' : '' }}</div>
				<div class="tool-wrapper">
					<a
						class="item download-link"
						target="_blank"
						:href="getDownloadFilePath(fileInfo)"
						:download="getFileNameComplete(fileInfo)"
					>
						<download-outlined title="下载" />
					</a>
					<a-tooltip placement="bottom">
						<template #title>
							<div>
								1. 点击文档以外的区域可退出查看<br />
								2. 按 Esc 键可退出查看
							</div>
						</template>
						<div class="item text-wrapper">
							<span class="text">操作提示</span>
							<bulb-outlined />
						</div>
					</a-tooltip>
					<close-outlined class="item" title="关闭预览" @click="closeMarkdownPreview" />
				</div>
			</div>
			<!-- mavon-editor 组件，配置项说明文档 https://www.npmjs.com/package/mavon-editor -->
			<a-spin :spinning="markdownLoading">
				<mavonEditor
					ref="mavonEditorRef"
					v-model="markdownText"
					:toolbars="toolbars"
					:editable="editable"
					:toolbarsFlag="toolbarsFlag"
					:externalLink="externalLink"
					:subfield="screenWidth > 768 ? true : false"
					defaultOpen="preview"
					@save="handleModifyFileContent"
				></mavonEditor>
			</a-spin>
		</div>
	</transition>
</template>

<script setup>
	import { ref, computed, watch, nextTick, getCurrentInstance } from 'vue'
	import { mavonEditor } from 'mavon-editor'
	import 'mavon-editor/dist/css/index.css'
	// 代码高亮样式表
	import '@/assets/mavonEditor/css/tomorrow-night.css'
	import '@/assets/mavonEditor/css/github-markdown.css'
	import { useMyResourceStore } from '@/store/myResource.js'
	import { getFilePreview, modifyFileContent } from '@/api/myResource/file.js'
	import { DownloadOutlined, BulbOutlined, CloseOutlined } from '@ant-design/icons-vue'
	import tool from '@/utils/tool'

	// 获取全局变量
	const { proxy } = getCurrentInstance()

	// 获取store
	const myResourceStore = useMyResourceStore()

	// 定义props
	const props = defineProps({
		fileInfo: Object,
		editable: Boolean,
		callback: Function
	})

	// 从proxy中获取$file方法
	const getFileNameComplete = (fileInfo) => {
		return proxy.$file.getFileNameComplete(fileInfo)
	}

	const getDownloadFilePath = (fileInfo) => {
		return proxy.$file.getDownloadFilePath(fileInfo)
	}

	// 响应式数据
	const visible = ref(false)
	const originalMarkdownText = ref('')
	const markdownText = ref('')
	const markdownLoading = ref(false)

	// 暴露visible属性给父组件
	defineExpose({ visible })

	// 工具栏配置
	const toolbars = {
		bold: true, // 粗体
		italic: true, // 斜体
		header: true, // 标题
		underline: true, // 下划线
		strikethrough: true, // 中划线
		mark: true, // 标记
		superscript: true, // 上角标
		subscript: true, // 下角标
		quote: true, // 引用
		ol: true, // 有序列表
		ul: true, // 无序列表
		link: true, // 链接
		imagelink: true, // 图片链接
		code: true, // code
		table: true, // 表格
		fullscreen: true, // 全屏编辑
		readmodel: true, // 沉浸式阅读
		htmlcode: true, // 展示html源码
		help: true, // 帮助
		/* 1.3.5 */
		undo: true, // 上一步
		redo: true, // 下一步
		trash: true, // 清空
		save: true, // 保存（触发 events 中的 save 事件）
		/* 1.4.2 */
		navigation: true, // 导航目录
		/* 2.1.8 */
		aligncenter: true, // 居中
		alignleft: true, // 左对齐
		alignright: true, // 右对齐
		/* 2.2.1 */
		subfield: true, // 单双栏模式
		preview: true // 预览
	}

	// 计算属性
	// 屏幕宽度
	const screenWidth = computed(() => {
		return myResourceStore.screenWidth
	})

	// 是否修改
	const isModify = computed(() => {
		return originalMarkdownText.value !== markdownText.value
	})

	// 外链 cdn 改为本地引入
	const externalLink = computed(() => {
		let context = process.env.NODE_ENV === 'production' ? '/' : '/'
		return {
			markdown_css: function () {
				// 这是你的markdown css文件路径
				return `${context}mavonEditor/css/github-markdown.css`
			},
			hljs_js: function () {
				// 这是你的hljs文件路径
				return `${context}mavonEditor/js/highlight.min.js`
			},
			hljs_css: function () {
				// 这是你的代码高亮配色文件路径
				return `${context}mavonEditor/css/tomorrow-night.css`
			},
			hljs_lang: function () {
				// 这是你的代码高亮语言解析路径
				return `${context}mavonEditor/js/lang.hljs.js`
			},
			katex_css: function () {
				// 这是你的katex配色方案路径路径
				return `${context}mavonEditor/css/katex.min.css`
			},
			katex_js: function () {
				// 这是你的katex.js路径
				return `${context}mavonEditor/js/katex.min.js`
			}
		}
	})

	// 工具栏是否展示
	const toolbarsFlag = computed(() => {
		return props.editable
	})

	// 监听 markdown 查看组件 显隐状态变化
	watch(visible, (val) => {
		if (val) {
			getMarkdownText()
			// 添加键盘 Esc 事件
			nextTick(() => {
				document.addEventListener('keyup', handleKeyup)
			})
		} else {
			document.removeEventListener('keyup', handleKeyup)
		}
	})

	// 键盘事件处理函数
	const handleKeyup = (e) => {
		if (e.key === 'Escape') {
			closeMarkdownPreview()
		}
	}

	/**
	 * 获取 markdown 文本内容
	 */
	const getMarkdownText = () => {
		markdownLoading.value = true
		getFilePreview({
			userFileId: props.fileInfo.userFileId,
			isMin: false,
			shareBatchNum: props.fileInfo.shareBatchNum,
			extractionCode: props.fileInfo.extractionCode,
			token: tool.data.get('TOKEN')
		}).then((res) => {
			markdownLoading.value = false
			originalMarkdownText.value = res
			markdownText.value = res
		})
	}

	/**
	 * 修改 markdown 文本内容
	 */
	const handleModifyFileContent = () => {
		markdownLoading.value = true
		modifyFileContent({
			userFileId: props.fileInfo.userFileId,
			fileContent: markdownText.value
		})
			.then((res) => {
				markdownLoading.value = false
				if (res.success) {
					proxy.$message.success('已保存')
					getMarkdownText()
				} else {
					proxy.$message.error(res.message)
				}
			})
			.catch((err) => {
				markdownLoading.value = false
				proxy.$message.error(err.message)
			})
	}

	/**
	 * 关闭 markdown 预览
	 */
	const closeMarkdownPreview = () => {
		visible.value = false
		props.callback('cancel')
	}
</script>

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

	.markdown-preview-wrapper {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		overflow: auto;
		width: 100%;
		height: 100vh;
		z-index: 2;
		text-align: center;
		display: flex;
		align-items: center;
		animation: imgPreviewAnimation 0.3s;
		-webkit-animation: imgPreviewAnimation 0.3s; /* Safari and Chrome */
		animation-iteration-count: 0.3;
		-webkit-animation-iteration-count: 0.3;
		animation-fill-mode: forwards;
		-webkit-animation-fill-mode: forwards; /* Safari 和 Chrome */
		@keyframes imgPreviewAnimation {
			0% {
				background: transparent;
			}
			100% {
				background: rgba(0, 0, 0, 0.8);
			}
		}
		@keyframes imgPreviewAnimation {
			0% {
				background: transparent;
			}
			100% {
				background: rgba(0, 0, 0, 0.8);
			}
		}
		.tip-wrapper {
			position: fixed;
			top: 0;
			left: 0;
			z-index: 2;
			background: rgba(0, 0, 0, 0.5);
			padding: 0 48px;
			width: 100%;
			height: 48px;
			line-height: 48px;
			color: #fff;
			font-size: 16px;
			display: flex;
			justify-content: space-between;
			.name {
				flex: 1;
				padding-right: 16px;
				text-align: left;
				overflow: hidden;
				text-overflow: ellipsis;
				white-space: nowrap;
				.un-save {
					color: @Warning;
					font-size: 14px;
				}
			}
			.tool-wrapper {
				flex: 1;
				display: flex;
				justify-content: flex-end;
				.item {
					margin-left: 16px;
					height: 48px;
					line-height: 48px;
					cursor: pointer;
					&:hover {
						opacity: 0.7;
					}
				}
				.save-img {
					margin: 16px 0;
					width: 16px;
					height: 16px;
				}
				.download-link {
					color: inherit;
					font-size: 18px;
				}
				.text-wrapper {
					.text {
						margin-right: 8px;
					}
				}
			}
		}

		:deep(.v-note-wrapper) {
			box-shadow: none !important;
			border: 1px solid @border-base;
			.v-note-op {
				border-bottom-color: @border-base;
				.op-image {
					.dropdown-item:nth-of-type(2) {
						display: none;
					}
				}
			}
			.v-note-navigation-wrapper {
				.v-note-navigation-content {
					h1,
					h2,
					h3,
					h4,
					h5,
					h6 {
						color: @primary-text;
						&:hover {
							color: @primary-text;
						}
					}
				}
			}
		}
		:deep(.v-note-wrapper:not(.fullscreen)) {
			margin: 56px auto 0 auto;
			width: 90vw;
			height: calc(100vh - 80px);
		}
	}
</style>
