<template>
    <div :class="['editor-box', self_disabled ? 'editor-disabled' : '']">
        <Toolbar v-if="!hideToolBar" class="editor-toolbar" :editor="editorRef" :default-config="toolbarConfig" :mode="mode" />
        <Editor
            v-model="valueHtml"
            class="editor-content"
            :style="{ height }"
            :mode="mode"
            :default-config="editorConfig"
            @on-created="handleCreated"
            @on-blur="handleBlur"
        />
    </div>
</template>

<script setup lang="ts" name="WangEditor">
import { nextTick, computed, inject, shallowRef, onBeforeUnmount } from "vue";
import { IToolbarConfig, IEditorConfig } from "@wangeditor/editor";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { uploadImg, uploadVideo } from "@/api/modules/upload";
import "@wangeditor/editor/dist/css/style.css";
import { formContextKey, formItemContextKey } from "element-plus";
// import { cloneDeep } from "lodash-es";
// 富文本 DOM 元素
const editorRef = shallowRef();

// 实列化编辑器
const handleCreated = (editor: any) => {
    editorRef.value = editor;
};

console.log(editorRef.value, "=editorRef.value=");
const $router = useRouter();
const routerValueName: string = $router.currentRoute.value.name as string;
const routerObj: any = {
    articleEditIndex: "article",
    productEditIndex: "product",
    bannerListIndex: "banner",
    downloadListIndex: "download",
    videoListIndex: "video",
    QAListIndex: "QA"
};
const routerName = ref(routerObj[routerValueName]);
// 接收父组件参数，并设置默认值
interface RichEditorProps {
    value: any; // 富文本值 ==> 必传
    toolbarConfig?: Partial<IToolbarConfig>; // 工具栏配置 ==> 非必传（默认为空）
    editorConfig?: Partial<IEditorConfig>; // 编辑器配置 ==> 非必传（默认为空）
    height?: string; // 富文本高度 ==> 非必传（默认为 500px）
    mode?: "default" | "simple"; // 富文本模式 ==> 非必传（默认为 default）
    hideToolBar?: boolean; // 是否隐藏工具栏 ==> 非必传（默认为false）
    disabled?: boolean; // 是否禁用编辑器 ==> 非必传（默认为false）
}
const props = withDefaults(defineProps<RichEditorProps>(), {
    toolbarConfig: () => {
        return {
            excludeKeys: []
        };
    },

    editorConfig: () => {
        return {
            placeholder: "请输入内容...",
            MENU_CONF: {}
            // parseElemHtml: (elemHtml: string, elem: HTMLElement, editor: any) => {
            //     console.log(editor, "========editor=========");
            //     console.log(elem.tagName, "=elem.tagName=");
            //     if (elem.tagName === "SPAN" && elem.querySelector("img")) {
            //         // 确保 span 元素可以正确显示 img
            //         elem.style.display = "inline-block";
            //     }
            //     return elemHtml;
            // }
        };
    },

    height: "500px",
    mode: "default",
    hideToolBar: false,
    disabled: false
});

// 获取 el-form 组件上下文
const formContext = inject(formContextKey, void 0);
// 获取 el-form-item 组件上下文
const formItemContext = inject(formItemContextKey, void 0);
// 判断是否禁用上传和删除
const self_disabled = computed(() => {
    return props.disabled || formContext?.disabled;
});

// 判断当前富文本编辑器是否禁用
if (self_disabled.value) nextTick(() => editorRef.value.disable());

// 富文本的内容监听，触发父组件改变，实现双向数据绑定
type EmitProps = {
    (e: "update:value", val: string): void;
    (e: "check-validate"): void;
};

const emit = defineEmits<EmitProps>();

const valueHtml = computed({
    get() {
        return props.value;
    },
    set(val: string) {
        // 防止富文本内容为空时，校验失败
        if (editorRef.value.isEmpty()) val = "";
        emit("update:value", val);
    }
});

/**
 * @description 图片自定义上传
 * @param file 上传的文件
 * @param insertFn 上传成功后的回调函数（插入到富文本编辑器中）
 * */
type InsertFnTypeImg = (url: string, alt?: string, href?: string) => void;
props.editorConfig.MENU_CONF!["uploadImage"] = {
    async customUpload(file: File, insertFn: InsertFnTypeImg) {
        if (!uploadImgValidate(file)) return;
        let formData = new FormData();
        formData.append("image", file);

        try {
            const result = await uploadImg(formData, routerName.value);
            if (result?.code === 0) {
                const { data } = result;
                insertFn(import.meta.env.VITE_APP_API_BASE_UPLOAD_URL + data.path);
            }
        } catch (error) {
            console.log(error);
        }
    }
};

// 图片上传前判断
const uploadImgValidate = (file: File): boolean => {
    console.log(file);
    return true;
};

/**
 * @description 视频自定义上传
 * @param file 上传的文件
 * @param insertFn 上传成功后的回调函数（插入到富文本编辑器中）
 * */
type InsertFnTypeVideo = (url: string, poster?: string) => void;
props.editorConfig.MENU_CONF!["uploadVideo"] = {
    async customUpload(file: File, insertFn: InsertFnTypeVideo) {
        if (!uploadVideoValidate(file)) return;
        let formData = new FormData();
        formData.append("file", file);
        try {
            const { data } = await uploadVideo(formData);
            insertFn(data.fileUrl);
        } catch (error) {
            console.log(error);
        }
    }
};

// 视频上传前判断
const uploadVideoValidate = (file: File): boolean => {
    console.log(file);
    return true;
};

// 编辑框失去焦点时触发
const handleBlur = () => {
    formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
    if (!editorRef.value) return;
    editorRef.value.destroy();
});

defineExpose({
    editor: editorRef
});
</script>

<style scoped lang="scss">
@import "./index.scss";
</style>
