<template>
	<transition
		name="fade"
		enter-active-class="ant-fade-enter ant-fade-enter-active"
		leave-active-class="ant-fade-leave ant-fade-leave-active"
	>
		<div class="code-preview-wrapper" v-show="visible" @keydown.ctrl.s.prevent="handleModifyFileContent">
			<!-- 顶部信息栏 -->
			<div class="tip-wrapper" v-if="visible">
				<div class="name" :title="$getFileNameComplete(fileInfo)">
					{{ $getFileNameComplete(fileInfo) }}
					<span class="un-save" v-show="isModify && !codeMirrorOptions.readOnly">（未保存）</span>
				</div>
				<div class="editor-preview">在线预览{{ codeMirrorOptions.readOnly ? '' : ' & 编辑' }}</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>
								操作提示:<br />
								1. 按 Esc 键可退出查看；<br />
								2. 支持在线编辑、保存、下载
							</div>
						</template>
						<div class="item text-wrapper">
							<span class="text">操作提示</span>
							<bulb-outlined />
						</div>
					</a-tooltip>
					<close-outlined class="item" title="关闭预览" @click="closeCodePreview" />
				</div>
			</div>

			<!-- 代码编辑区域 -->
			<div class="code-editor-wrapper">
				<div class="operate-wrapper">
					<save-outlined
						v-show="isModify && !codeMirrorOptions.readOnly"
						class="save-icon"
						title="保存（ctrl+s）"
						@click="handleModifyFileContent"
					/>
					<a-form class="editor-set-form" :model="codeMirrorOptions" layout="inline" size="small">
						<a-form-item>
							<a-checkbox v-model:checked="codeMirrorOptions.lineWrapping" @change="handleChangeCodeMirrorOption">
								自动换行
							</a-checkbox>
						</a-form-item>

						<a-form-item>
							<a-select v-model:value="codeMirrorCustomOptions.fontSize" style="width: 96px" show-search>
								<a-select-option v-for="size in fontSizeList" :key="size" :value="size">
									{{ size }} px
								</a-select-option>
							</a-select>
						</a-form-item>

						<a-form-item label="代码语言">
							<a-select
								v-model:value="codeMirrorOptions.mode"
								style="width: 120px"
								show-search
								@change="handleChangeCodeMirrorOption"
							>
								<a-select-option
									v-for="[key, value] in Object.entries(fileSuffixCodeModeMap)"
									:key="key"
									:value="value[1].mime"
								>
									{{ value[1].language }}
								</a-select-option>
							</a-select>
						</a-form-item>

						<a-form-item label="主题">
							<a-select
								v-model:value="codeMirrorOptions.theme"
								style="width: 190px"
								show-search
								@change="handleChangeCodeMirrorOption"
							>
								<a-select-option value="default">default</a-select-option>
								<a-select-option v-for="theme in codeMirrorThemeList" :key="theme" :value="theme">
									{{ theme }}
								</a-select-option>
							</a-select>
						</a-form-item>
					</a-form>
				</div>

				<a-spin :spinning="codeMirrorLoading">
					<!-- <Codemirror
						v-if="isShow"
						ref="codemirrorRef"
						v-model:value="codeMirrorText"
						:options="codeMirrorOptions"
						class="code-editor"
						:style="{ fontSize: `${codeMirrorCustomOptions.fontSize}px` }"
					/> -->
				</a-spin>
			</div>
		</div>
	</transition>
</template>

<script setup>
	import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
	import { message } from 'ant-design-vue'
	// import { Codemirror } from 'codemirror-editor-vue3'
	// 启用基础样式
	// import 'codemirror-editor-vue3/dist/style.css'
	// // 启用编程语言
	// import 'codemirror/mode/javascript/javascript.js'
	// import 'codemirror/mode/xml/xml.js'
	// import 'codemirror/mode/css/css.js'
	// // 启用主题
	// import 'codemirror/lib/codemirror.css'
	// import 'codemirror/theme/monokai.css'
	// import 'codemirror/theme/material.css'
	import { DownloadOutlined, BulbOutlined, CloseOutlined, SaveOutlined } from '@ant-design/icons-vue'
	import { useMyResourceStore } from '@/store/myResource'
	import { getFilePreview, modifyFileContent } from '@/api/myResource/file'
	import { fontSizeList, fileSuffixCodeModeMap, codeMirrorThemeList } from '@/libs/map'

	// import 'codemirror/lib/codemirror.css'
	// import './theme.js'
	// import './mode.js'
	// import './fold.js'

	// 状态管理
	const store = useMyResourceStore()

	const visible = ref(false)
	const originalCodeText = ref('')
	const codeMirrorText = ref('')
	const codeMirrorLoading = ref(false)
	const codeMirrorOptions = ref({
		tabSize: 4,
		mode: 'text/html',
		theme: 'default',
		readOnly: true,
		lineNumbers: true,
		line: true,
		autoCloseBrackets: true,
		foldGutter: true,
		lineWrapping: true,
		gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers']
	})
	const codeMirrorCustomOptions = ref({
		fontSize: 14
	})
	const isShow = ref(true)

	// 计算属性
	const screenWidth = computed(() => store.screenWidth)
	const isModify = computed(() => originalCodeText.value !== codeMirrorText.value)

	// 方法
	function getCodeText() {
		codeMirrorLoading.value = true
		getFilePreview({
			userFileId: fileInfo.userFileId,
			isMin: false,
			shareBatchNum: fileInfo.shareBatchNum,
			extractionCode: fileInfo.extractionCode,
			token: $common.getCookies($config.tokenKeyName)
		}).then((res) => {
			codeMirrorLoading.value = false
			originalCodeText.value = typeof res === 'object' ? JSON.stringify(res) : res
			codeMirrorText.value = originalCodeText.value + ''
		})
	}

	function handleModifyFileContent() {
		if (!isModify.value || codeMirrorOptions.value.readOnly) {
			return false
		}
		codeMirrorLoading.value = true
		modifyFileContent({
			userFileId: fileInfo.userFileId,
			fileContent: codeMirrorText.value
		})
			.then((res) => {
				codeMirrorLoading.value = false
				if (res.success) {
					message.success('已保存')
					getCodeText()
				} else {
					message.error(res.message)
				}
			})
			.catch((err) => {
				codeMirrorLoading.value = false
				message.error(err.message)
			})
	}

	function handleChangeCodeMirrorOption() {
		isShow.value = false
		isShow.value = true
	}

	function closeCodePreview() {
		visible.value = false
		callback('cancel')
	}

	// 监听
	watch(visible, (val) => {
		if (val) {
			let fileSuffix = fileInfo.extendName.toLowerCase()
			if (fileSuffix === 'yaml') {
				fileSuffix = 'yml'
			}
			if (fileSuffixCodeModeMap.has(fileSuffix)) {
				codeMirrorOptions.value.mode = fileSuffixCodeModeMap.get(fileSuffix).mime
			}
			codeMirrorOptions.value.readOnly = !isEdit //  设置编辑器是否只读
			codeMirrorOptions.value.theme = localStorage.getItem('qiwen_file_codemirror_theme') || 'default'
			getCodeText()
			// 添加键盘 Esc 事件
			nextTick(() => {
				document.addEventListener('keyup', (e) => {
					if (e.keyCode === 27) {
						closeCodePreview()
					}
				})
			})
		} else {
			document.removeEventListener('keyup', (e) => {
				if (e.keyCode === 27) {
					closeCodePreview()
				}
			})
		}
	})

	watch(
		() => codeMirrorOptions.value.theme,
		(val) => {
			localStorage.setItem('qiwen_file_codemirror_theme', val)
		}
	)

	// 生命周期钩子
	onMounted(() => {})

	onUnmounted(() => {})

	defineExpose({
		visible
	})
</script>

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

	.code-preview-wrapper {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		overflow: auto;
		width: 100%;
		height: 100vh;
		z-index: 2;
		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;
					}
				}
				.download-link {
					color: inherit;
					font-size: 18px;
				}
				.text-wrapper {
					.text {
						margin-right: 8px;
					}
				}
			}
		}
		.code-editor-wrapper {
			margin: 56px auto 0 auto;
			width: 90vw;
			height: calc(100vh - 80px);
			.operate-wrapper {
				display: flex;
				justify-content: space-between;
				align-items: center;
				border-radius: 8px 8px 0 0;
				border-bottom: 1px solid @BorderBase;
				padding: 8px 16px;
				background: #fff;
				.save-icon {
					font-size: 20px;
					cursor: pointer;
					color: @Info;
					font-weight: 550;
					&:hover {
						opacity: 0.5;
					}
				}
				.editor-set-form {
					flex: 1;
					text-align: right;
					// >>> .el-form-item {
					//   margin-bottom: 0;
					//   &.font-size {
					//     .el-form-item__content {
					//       .el-select {
					//         width: 96px;
					//       }
					//     }
					//   }
					//   &.lanaguage {
					//     .el-form-item__content {
					//       .el-select {
					//         width: 120px;
					//       }
					//     }
					//   }
					//   &.theme {
					//     .el-form-item__content {
					//       .el-select {
					//         width: 190px;
					//       }
					//     }
					//   }
					// }
				}
			}
			.code-editor {
				height: calc(100vh - 129px);
				//   >>> .CodeMirror {
				//     border-radius: 0 0 8px 8px;
				//     height: inherit;
				//     font-size: inherit;
				//     * {
				//       font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace !important;
				//     }
				//     .CodeMirror-vscrollbar, .CodeMirror-hscrollbar {
				//       display: none !important;
				//     }
				//     .CodeMirror-scroll {
				//       width: 100%;
				//       padding: 8px 0 0 0;
				//       line-height: 1.5;
				//       font-size: inherit;
				//       setScrollbar(12px, transparent, #C0C4CC);
				//     }
				//   }
			}
		}
	}
	.editor-preveiw {
		margin-left: -102px;
	}
	.editor-preveiw[data-v-8897ab08] {
		margin-left: -102px;
	}
	/deep/ .el-checkbox__input.is-checked + .el-checkbox__label {
		color: #29175b;
	}
	/deep/ .el-checkbox__input.is-checked .el-checkbox__inner,
	.el-checkbox__input.is-indeterminate .el-checkbox__inner {
		background-color: #29175b;
		border-color: #29175b;
	}
	/deep/ .el-select .el-input.is-focus .el-input__inner {
		border-color: #29175b;
	}
	/deep/ .el-select-dropdown__item.selected {
		color: #29175b !important;
		font-weight: 700;
	}
</style>
