<template>
    <div>
        <el-form ref="dataFormRef" :model="props.currFlowForm" :rules="dataRules" label-width="80px"
                 v-loading="loading" v-if="!props.currFlowForm.isForm">
            <el-row :gutter="24">
                <el-col :span="12" class="mb20">
                    <el-form-item :label="t('formoption.formType')" prop="formType">
                        <el-select v-model="props.currFlowForm.formType" :placeholder="t('formoption.inputFormTypeTip')" clearable
                                   filterable
                                   @change="formTypeChange">
                            <el-option v-for="(item, index) in DIC_PROP.FORM_TYPE" :key="index" :label="item.label"
                                       :value="item.value"></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>

                <el-col :span="12" class="mb20">
                    <el-form-item :label="t('formoption.formId')" prop="formId">
                        <el-select v-model="props.currFlowForm.formId" :placeholder="t('formoption.inputFormIdTip')" clearable
                                   filterable
                                   @change="formIdChange">
                            <el-option v-for="(item, index) in dicData.formIdByType" :key="index"
                                       :label="item.formName" :value="item.id"></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <div style="margin-bottom: 10px; color: #72767b;">请拖拽字段到设计器中</div>
        <el-container>
            <el-aside width="200px">
                <el-divider> 系统字段 </el-divider>
                <template v-for="(item, index) in data.sysFields" :key="index">
                    <div :draggable="item.prop!=='_define_'" v-if="item.label"
                         class="tinymce-form-prop" @dragstart="dragNode(item)">
                        {{ item.label }}
                    </div>
                </template>
                <el-divider> 表单字段 </el-divider>
                <template v-for="(item, index) in data.formFields" :key="index">
                    <div draggable="true" v-if="item.label"
                         class="tinymce-form-prop" @dragstart="dragNode(item)">
                        {{ item.label }}
                    </div>
                </template>
            </el-aside>
            <el-main>
                <editor v-model="props.currFlowForm.printInfo" @dragover="allowDrop" @drop="drop"
                        :init="init"
                        :disabled="loading"
                        :id="tinymceId">
                </editor>
                <footer class="el-dialog__footer">
                    <span class="dialog-footer">
                        <el-button @click="cancelClick">清空模板</el-button>
                        <el-button type="primary" @click="confirmClick">保存模板</el-button>
                    </span>
                </footer>
            </el-main>
        </el-container>
    </div>
</template>

<script setup lang="ts" name="TinymceEditor">
    import tinymce from "tinymce/tinymce";
    import Editor from "@tinymce/tinymce-vue";
    import "tinymce/icons/default/icons";
    import "tinymce/themes/silver";
    import "tinymce/plugins/print";
    import "tinymce/plugins/hr";
    import "tinymce/plugins/anchor";
    import "tinymce/plugins/fullscreen";
    import "tinymce/plugins/pagebreak";
    import "tinymce/plugins/image";
    import "tinymce/plugins/table";
    import "tinymce/plugins/lists";
    import "tinymce/plugins/wordcount";
    import "tinymce/plugins/preview";
    import "tinymce/plugins/emoticons";
    import "tinymce/plugins/emoticons/js/emojis.js";
    import "tinymce/plugins/code";
    import "tinymce/plugins/link";
    import "tinymce/plugins/advlist";
    import "tinymce/plugins/autoresize";
    import "tinymce/plugins/quickbars";
    import "tinymce/plugins/nonbreaking";
    import "tinymce/plugins/searchreplace";
    import "tinymce/plugins/autolink";
    import "tinymce/plugins/directionality";
    import "tinymce/plugins/visualblocks";
    import "tinymce/plugins/visualchars";
    import "tinymce/plugins/charmap";
    import "tinymce/plugins/nonbreaking";
    import "tinymce/plugins/insertdatetime";
    import "tinymce/plugins/importcss";
    import "tinymce/plugins/help";
    import {buildFieldPerms} from "/@/flow/utils/form-perm";
    import {validateNull} from "/@/utils/validate";
    import {useMessage} from "/@/hooks/message";
    import {PROP_CONST} from "../../support/prop-const";
    import {onLoadDicUrl} from "../convert-name/convert";
    import {DIC_PROP} from "../../support/dict-prop";
    import {listPrintTemp, savePrintTemp} from "/@/api/jsonflow/form-option";
    import {useI18n} from "vue-i18n";
    import {parseWithFunctions} from "../../index";
    import {deepClone} from "/@/utils/other";

    const $message = useMessage();
    const { t } = useI18n()
    const props = defineProps({
        currFlowForm: {
            type: Object,
            default: null,
        },
        baseUrl: {
            type: String,
            default: "",
        },
        plugins: {
            type: [String, Array],
            default:
                "print preview hr anchor fullscreen pagebreak help searchreplace autoresize quickbars autolink directionality code visualblocks visualchars image link table nonbreaking charmap insertdatetime advlist lists wordcount emoticons help",
        },
        toolbar: {
            type: [String, Array],
            default:
                "code undo redo | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
              blocks fontfamily fontsize | bullist numlist | blockquote subscript superscript removeformat | \
              table image charmap pagebreak insertdatetime emoticons hr | print preview fullscreen | styleselect formatselect fontselect fontsizeselect",
        },
    });

    const loading = ref(false);
    const tinymceId = ref(
        "tinymce-id-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
    );

    // 定义init初始化对象
    const init = reactive({
        selector: "#" + tinymceId.value,
        language_url: "/flow/tinymce/langs/zh_CN.js",
        language: "zh_CN",
        skin_url: "/flow/tinymce/skins/ui/oxide",
        branding: false,
        promotion: false,
        menubar: "file edit view insert format tools table help",
        paste_data_images: true,
        image_dimensions: false,
        plugins: props.plugins,
        toolbar: props.toolbar,
        quickbars_image_toolbar: "alignleft aligncenter alignright | rotateleft rotateright | imageoptions",
        editimage_toolbar: "rotateleft rotateright | flipv fliph | editimage imageoptions",
        font_formats: "Arial=arial,helvetica,sans-serif; 宋体=SimSun; 微软雅黑=Microsoft Yahei; Impact=impact,chicago;",
        fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px 64px 72px",
        image_caption: true,
        editimage_cors_hosts: ["picsum.photos"],
        noneditable_class: "mceNonEditable",
        toolbar_mode: "wrap",
        content_style: "body { font-family:Helvetica,Arial,sans-serif; font-size:16px }",
        image_advtab: true,
        importcss_append: true,
        paste_webkit_styles: "all",
        paste_merge_formats: true,
        nonbreaking_force_tab: false,
        paste_auto_cleanup_on_paste: false,
        file_picker_types: "file",
        quickbars_insert_toolbar: "",
        quickbars_selection_toolbar: "bold italic | quicklink h2 h3 blockquote quickimage quicktable",
        autoresize_bottom_margin: 50,
        autoresize_max_height: 500,
        autoresize_min_height: 350,
        content_css: "/flow/tinymce/skins/content/default/content.css",
        images_upload_handler: (blobInfo, success, failure) => {
            // base64形式上传图片
            const img = 'data:image/jpeg;base64,' + blobInfo.base64()
            success(img)
        }
    });

    const data = reactive({
        formFields: [],
        sysFields: deepClone(PROP_CONST.SYS_FIELDS),
    })
    const prop = reactive({
        propId: null,
        prop: null,
        propVar: null,
        propType: null,
        label: null
    });
    // 开始拖拽
    function dragNode(item) {
        prop.propId = item.propId
        prop.prop = item.prop
        prop.propVar = "${" + item.prop + "}"
        prop.subForm = item.subForm
        prop.propType = item.propType
        prop.label = item.label
    }

    function allowDrop(e) {
        tinymce.activeEditor.selection.select(e.target, true).focus()
        tinymce.activeEditor.selection.collapse(false)
        e.preventDefault();
    }
    function drop(e) {
        let tagName = e.target.tagName;
        // 判断子表单信息
        if (prop.subForm && tagName !== 'TD') {
            $message.warning('子表单字段只能拖拽到表格中，请先创建表格');
            return
        } else {
            // 处理子表单
            if (prop.propType && prop.propType.indexOf(PROP_CONST.FORM_DESIGN.subForm) !== -1) {
                // TODO 创建对应列的表格
            }
        }
        let content = prop.propVar
        tinymce.activeEditor.insertContent(content)
    }

    function extractedFormFields(formFields) {
        formFields.forEach(each => {
            if (each.subForm) {
                each.prop = each.subForm + '.' + each.prop
                each.label += "(子表单)"
            }
        })
        data.formFields = formFields
    }

    function buildFormFieldPerms(formInfoStr) {
        if (validateNull(formInfoStr)) return
        let formInfo = parseWithFunctions(formInfoStr, true)
        let formFields = []
        buildFieldPerms(formFields, formInfo.widgetList);
        extractedFormFields(formFields)
    }

    // 定义查询字典
    const dicData = reactive({});
    const onLoad = onLoadDicUrl({key: "formId"});

    // 定义校验规则
    const dataRules = ref({
        formType: [{required: true, message: '表单来源不能为空', trigger: 'blur'}],
        formId: [{required: true, message: '表单名称不能为空', trigger: 'blur'}],
    })

    const formTypeChange = (value, isInit) => {
        if (value) {
            dicData.formIdByType = dicData.formId.filter(f => f.type === value)
        } else dicData.formIdByType = []
        clearFormFields()
        if (!isInit) props.currFlowForm.formId = null
    }

    const formIdChange = (value) => {
        clearFormFields()
        if (!value) return
        let find = dicData.formIdByType.find(f => f.id === value);
        // 表单实例
        if (!validateNull(props.currFlowForm.formInfo)) {
            handleFormPrintDef(value, props.currFlowForm.type, props.currFlowForm)
            return;
        }
        props.currFlowForm.formName = find.formName
        props.currFlowForm.path = find.path
        handleFormPrintDef(value, props.currFlowForm.type, find)
    }

    function clearFormFields(){
        data.formFields = [];
        props.currFlowForm.printInfo = null
        tinymce.activeEditor.setContent('')
    }

    // 查询字段信息
    function handleFormPrintDef(formId, type, find) {
        clearFormFields()
        listPrintTemp({
            flowInstId: props.currFlowForm.flowInstId,
            type: type, formType: props.currFlowForm.formType, formId: formId,
        }).then(resp => {
            let res = resp.data;
            props.currFlowForm.printInfo = res.printInfo
            if (!validateNull(res.columns)) extractedFormFields(res.columns)
            else if (!validateNull(find.formInfo)) {
                buildFormFieldPerms(find.formInfo);
            } else if (props.currFlowForm.formType === DIC_PROP.FORM_TYPE[0].value){
                $message.warning("当前选择的设计表单无字段信息，请先在《表单设计器》中设计")
            } else {
                $message.warning("当前选择的系统表单无字段信息，请先在表单设计中录入")
            }
        })
        .catch(() => {
            $message.error("获取表单字段定义失败");
        })
    }

    async function initFormParams() {
        await onLoad(dicData);
        // 初始化
        props.currFlowForm.type = DIC_PROP.FORM_DATA_TYPE[2].value
        let formId = props.currFlowForm.formId;
        if (formId) {
            formTypeChange(props.currFlowForm.formType, true)
            formIdChange(formId)
        }
    }

    async function confirmClick() {
        await savePrintTemp(props.currFlowForm)
        useMessage().success(t('common.editSuccessText'));
    }
    async function cancelClick() {
        props.currFlowForm.printInfo = null
        tinymce.activeEditor.setContent('')
        await confirmClick()
    }

    // 监听变化
    watch(
        () => props.currFlowForm.id,
        async () => {
            await initFormParams()
        }
    );

    // 初始化
    onMounted(async () => {
        await initFormParams()
        await tinymce.init({});
    });
</script>

<style lang="scss" scoped>
  .el-dialog__footer {
    text-align: center;
    margin-top: 10px;

    .dialog-footer {
      text-align: center;
    }
  }
</style>

<style lang="scss">
  @import "/flow/tinymce/skins/content/default/content.css";

  .tox-tinymce {
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    .tox-statusbar {
      display: none;
    }
  }

  /* 在el-dialog中z-index被遮挡 */
  .tox-tinymce-aux {
    z-index: 9999 !important;
  }

  .tinymce-form-prop {
    cursor: move;
    background: rgb(245, 246, 246);
    border: 1px solid rgb(245, 246, 246);
    border-radius: 8px;
    margin-bottom: 5px;
    padding: 8px;
    
    &:hover {
      color: #0960bd;
      outline: 1px dashed #0960bd;
      border: 1px solid #0960bd;
    }
  }
</style>
