<template>
	<div class="markdown-editor">
		<div class="editor-tabs">
			<el-tabs v-model="activeTab" @tab-click="handleTabClick">
				<el-tab-pane 
					label="编辑" 
					name="edit"
					:disabled="readonly"
				>
					<div class="editor-container">
						<el-input
							v-model="markdownContent"
							type="textarea"
							:rows="20"
							placeholder="请输入Markdown格式的内容..."
							@input="handleInput"
							class="markdown-input"
							:disabled="readonly"
						/>
					</div>
				</el-tab-pane>
				<el-tab-pane label="预览" name="preview">
					<div class="preview-container" v-html="previewHtml"></div>
				</el-tab-pane>
			</el-tabs>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
import { marked } from 'marked';
import DOMPurify from 'dompurify';

const props = defineProps({
	modelValue: {
		type: String,
		default: ''
	},
	readonly: {
		type: Boolean,
		default: false
	}
});

const emit = defineEmits(['update:modelValue']);

const activeTab = ref('edit');
const markdownContent = ref('');

// 配置marked选项
marked.setOptions({
	breaks: true,
	gfm: true,
});

// 计算预览HTML
const previewHtml = computed(() => {
	if (!markdownContent.value) return '';
	try {
		const html = marked.parse(markdownContent.value) as string;
		return DOMPurify.sanitize(html);
	} catch (error) {
		console.error('Markdown解析错误:', error);
		return markdownContent.value;
	}
});

// 处理输入
const handleInput = () => {
	emit('update:modelValue', markdownContent.value);
};

// 处理标签页切换
const handleTabClick = (tab: any) => {
	// 如果是只读模式，不允许切换到编辑标签页
	if (props.readonly && tab.paneName === 'edit') {
		return;
	}
	activeTab.value = tab.paneName;
};

// 监听外部值变化
watch(() => props.modelValue, (newValue) => {
	if (newValue !== markdownContent.value) {
		markdownContent.value = newValue || '';
	}
}, { immediate: true });

// 监听只读状态变化
watch(() => props.readonly, (isReadonly) => {
	if (isReadonly) {
		// 只读模式下默认选中预览标签页
		activeTab.value = 'preview';
	} else {
		// 编辑模式下默认选中编辑标签页
		activeTab.value = 'edit';
	}
}, { immediate: true });

// 组件挂载时初始化
onMounted(() => {
	markdownContent.value = props.modelValue || '';
	// 根据只读状态设置默认标签页
	if (props.readonly) {
		activeTab.value = 'preview';
	}
});
</script>

<style scoped>
.markdown-editor {
	border: 1px solid #dcdfe6;
	border-radius: 4px;
	overflow: hidden;
}

.editor-tabs {
	height: 100%;
}

.editor-container {
	padding: 0;
}

.markdown-input {
	height: 400px;
}

.markdown-input :deep(.el-textarea__inner) {
	height: 100%;
	resize: none;
	font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
	font-size: 14px;
	line-height: 1.5;
	border: none;
	border-radius: 0;
}

.markdown-input :deep(.el-textarea__inner:disabled) {
	background-color: #f5f7fa;
	color: #909399;
	cursor: not-allowed;
}

.preview-container {
	padding: 16px;
	height: 400px;
	overflow-y: auto;
	border: 1px solid #f0f0f0;
	background: #fff;
}

.preview-container :deep(h1) {
	font-size: 24px;
	margin: 16px 0 8px 0;
	border-bottom: 1px solid #eaecef;
	padding-bottom: 8px;
}

.preview-container :deep(h2) {
	font-size: 20px;
	margin: 14px 0 6px 0;
	border-bottom: 1px solid #eaecef;
	padding-bottom: 6px;
}

.preview-container :deep(h3) {
	font-size: 18px;
	margin: 12px 0 4px 0;
}

.preview-container :deep(h4) {
	font-size: 16px;
	margin: 10px 0 4px 0;
}

.preview-container :deep(h5) {
	font-size: 14px;
	margin: 8px 0 4px 0;
}

.preview-container :deep(h6) {
	font-size: 12px;
	margin: 6px 0 4px 0;
}

.preview-container :deep(p) {
	margin: 8px 0;
	line-height: 1.6;
}

.preview-container :deep(ul), 
.preview-container :deep(ol) {
	margin: 8px 0;
	padding-left: 24px;
}

.preview-container :deep(li) {
	margin: 4px 0;
}

.preview-container :deep(blockquote) {
	margin: 8px 0;
	padding: 8px 16px;
	background: #f8f9fa;
	border-left: 4px solid #dfe2e5;
}

.preview-container :deep(code) {
	background: #f6f8fa;
	padding: 2px 4px;
	border-radius: 3px;
	font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
	font-size: 13px;
}

.preview-container :deep(pre) {
	background: #f6f8fa;
	padding: 16px;
	border-radius: 6px;
	overflow-x: auto;
	margin: 8px 0;
}

.preview-container :deep(pre code) {
	background: none;
	padding: 0;
}

.preview-container :deep(table) {
	border-collapse: collapse;
	width: 100%;
	margin: 8px 0;
}

.preview-container :deep(th),
.preview-container :deep(td) {
	border: 1px solid #dfe2e5;
	padding: 8px 12px;
	text-align: left;
}

.preview-container :deep(th) {
	background: #f6f8fa;
	font-weight: 600;
}

.preview-container :deep(a) {
	color: #0366d6;
	text-decoration: none;
}

.preview-container :deep(a:hover) {
	text-decoration: underline;
}
</style>

