<template>
    <div style="border: 1px solid #ccc; margin-top: 10px">
        <Toolbar
            :editor="editorRef"
            :defaultConfig="toolbarConfig"
            :mode="mode"
            style="border-bottom: 1px solid #ccc"
        />
        <Editor
            :defaultConfig="editorConfig"
            :mode="mode"
            v-model="valueHtml"
            style="height: 400px; overflow-y: hidden"
            @onCreated="handleCreated"
            @onChange="handleChange"
            @onDestroyed="handleDestroyed"
            @customAlert="customAlert"
            @customPaste="customPaste"
        />
    </div>
</template>

<script setup>
import axios from 'axios';
import { ref, watch, onMounted, onUnmounted } from 'vue';
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { DomEditor } from '@wangeditor/editor';
import { getToken } from '@/utils/auth';

const { proxy } = getCurrentInstance();
const emits = defineEmits(['update:modelValue']);

const props = defineProps({
    /* 编辑器的内容 */
    modelValue: {
        type: String,
    },
    /* 高度 */
    height: {
        type: Number,
        default: null,
    },
    /* 最小高度 */
    minHeight: {
        type: Number,
        default: null,
    },
    /* 只读 */
    readOnly: {
        type: Boolean,
        default: false,
    },
    /* 上传文件大小限制(MB) */
    fileSize: {
        type: Number,
        default: 5,
    },
    /* 类型（base64格式、url格式） */
    type: {
        type: String,
        default: 'url',
    },
    // 上传服务器的文件夹路径
    filePath: {
        type: String,
        default: 'editor/article',
    },
});

const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + '/common/upload'); // 上传的图片服务器地址
const headers = ref({
    Authorization: 'Bearer ' + getToken(),
});
const filePath = ref({ filePath: props.filePath ? props.filePath : '' });

// 编辑器实例，必须用 shallowRef，重要！
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref('');
const mode = ref('default');

watch(
    () => props.modelValue,
    v => {
        if (v !== valueHtml.value) {
            valueHtml.value = v === undefined ? '<p></p>' : v;
        }
    },
    { immediate: true }
);

// 模拟 ajax 异步获取内容
onMounted(() => {});

const toolbarConfig = {
    excludeKeys: ['group-video'],
};

const editorConfig = {
    placeholder: '请输入内容...',
    MENU_CONF: {
        uploadImage: {
            customUpload: async (file, insertFn) => {
                const formData = new FormData(); // 创建 FormData 对象
                formData.append('file', file);
                handleUpload(formData, insertFn);
            },
            // 上传之前触发
            onBeforeUpload(file) {
                handleBeforeUpload(file);
            },
        },
    },
};

// 上传前校检格式和大小
function handleBeforeUpload(file) {
    const type = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg'];
    const isJPG = type.includes(file.type);
    //检验文件格式
    if (!isJPG) {
        proxy.$modal.msgError(`图片格式错误!`);
        return false;
    }
    // 校检文件大小
    if (props.fileSize) {
        const isLt = file.size / 1024 / 1024 < props.fileSize;
        if (!isLt) {
            proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
            return false;
        }
    }
    return true;
}

// 上传前校检格式和大小
function handleUpload(formData, insertFn) {
    const instance = axios.create({
        baseURL: import.meta.env.VITE_APP_BASE_API,
        timeout: 5000,
    });

    // 请求拦截器（动态添加 token）
    instance.interceptors.request.use(config => {
        config.headers.Authorization = 'Bearer ' + getToken();
        return config;
    });

    // 发送请求
    instance
        .post('/common/upload', formData, {
            headers: {
                'Content-Type': 'multipart/form-data',
            },
        })
        .then(res => {
            // console.log('上传成功:', res);
            insertFn(res.data?.url, '图片', res.data?.url);
        })
        .catch(err => {
            console.error('上传失败:', err);
        });
}

// 组件销毁时，也及时销毁编辑器，重要！
onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;

    editor.destroy();
});

// 编辑器回调函数
const handleCreated = editor => {
    editorRef.value = editor; // 记录 editor 实例，重要！
};
const handleChange = editor => {
    // const toolbar = DomEditor.getToolbar(editor);
    let html = editor.getHtml();
    emits('update:modelValue', html);
};
const handleDestroyed = editor => {
    console.log('destroyed', editor);
};

const customAlert = (info, type) => {
    alert(`【自定义提示】${type} - ${info}`);
};
const customPaste = (editor, event, callback) => {
    // console.log('ClipboardEvent 粘贴事件对象', event);
    const text = event.clipboardData.getData('text/plain');
    const rtf = event.clipboardData.getData('text/rtf');
    // 自定义插入内容
    if (text) {
        editor.insertText(text);
    } else if (rtf) {
        editor.insertText(rtf);
    }

    // 返回值（注意，vue 事件的返回值，不能用 return）
    callback(false); // 返回 false ，阻止默认粘贴行为
};

const insertText = () => {
    const editor = editorRef.value;
    if (editor == null) return;

    editor.insertText('hello world');
};

const printHtml = () => {
    const editor = editorRef.value;
    if (editor == null) return;
    console.log(editor.getHtml());
};

const disable = () => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.disable();
};
</script>
