<template>
  <div>
    <div style="width: 250px; height: 100%; display: inline-block; vertical-align: top; border-right: 1px solid #999">
      <div class="title">预定义字段(点击插入光标位置)</div>
      <div class="fieldList">
        <div class="fieldItem" v-for="i in fieldList">
          <div class="btn" @click="insertText(i)">
            {{ i.varLabel }}
          </div>
        </div>
      </div>
    </div>
    <div style="width: calc(100% - 251px); display: inline-block; vertical-align: top; height: calc(100vh - 50px - 34px)">
      <umo-editor v-bind="options" ref="editorRef" />
    </div>
  </div>
</template>

<script setup>
import { UmoEditor } from '@umoteam/editor';
import { getPrintTemplate, updatePrintTemplate } from '@/api/oa/base/printTemplate';
import router from '@/router/index.js';
import { useRoute } from 'vue-router';
import { getBaseTemplateVariableList } from '@/api/oa/base/templateVariable/index.js';

const route = useRoute();

const template = ref({});

const editorRef = ref();

const fieldList = ref([]);

const templateData = {
  data0: '合计-1',
  data1: '合同总价-1',
  data2: '大写数字-1',
  '中文字段': 'zhongwenziduan',
  table0: [
    {
      field1: '1',
      field2: '2',
      field3: '3',
      field4: '4',
      field5: '5',
      field6: '6',
      field7: '7'
    },
    {
      field1: '11',
      field2: '22',
      field3: '33',
      field4: '44',
      field5: '55',
      field6: '66',
      field7: '77'
    },
    {
      field1: '111',
      field2: '222',
      field3: '333',
      field4: '444',
      field5: '555',
      field6: '666',
      field7: '777'
    }
  ]
};
const options = ref({
  document: {
    title: '',
    content: {
      type: 'doc',
      content: []
    },
    placeholder: {
      en_US: 'Please enter the document content...',
      zh_CN: '请输入文档内容...'
    },
    enableSpellcheck: true,
    enableMarkdown: false,
    enableBubbleMenu: true,
    enableBlockMenu: true,
    readOnly: false,
    autofocus: true,
    characterLimit: 0,
    typographyRules: {
      emDash: false
    },
    editorProps: {},
    parseOptions: {
      preserveWhitespace: 'full'
    },
    autoSave: {
      enabled: true,
      interval: 1000 * 60 * 5
    }
  },
  page: {
    showBreakMarks: false
  },
  onSave: async (e) => {
    const editor = editorRef.value;
    template.value.templateData = JSON.stringify(e.json);
    const res = await updatePrintTemplate(template.value);
    ElMessage.success(res.msg);
    if (res.code === 200) {
      return true;
    }
  }
});
const renderTemplate = (str, data) => {
  return str.replace(/#\{(.*?)\}/g, (_, path) => {
    // console.log(path.split('.').reduce((o, k) => o?.[k], data) ?? '');
    return path.split('.').reduce((o, k) => o?.[k], data) ?? '';
  });
};
const rowRenderTemplate = (str, data) => {
  return str.replace(/\^\{(.*?)\}/g, (_, path) => {
    return path.split('.').reduce((o, k) => o?.[k], data) ?? '';
  });
};
const hasCaretPattern = (arr) => {
  // 正则匹配 ^{xxx}
  const regex = /\^\{.*?\}/;

  function traverse(items) {
    for (const item of items) {
      if (item.text && regex.test(item.text)) {
        return true; // 找到匹配
      }
      if (item.content && Array.isArray(item.content)) {
        if (traverse(item.content)) {
          return true;
        }
      }
    }
    return false;
  }

  return traverse(arr);
};

const fillRowData = (e, data) => {
  if (Array.isArray(e.content)) {
    e.content.map((item) => {
      return fillRowData(item, data);
    });
  } else {
    e.text = rowRenderTemplate(e.text || '', data);
  }
  return e;
};
const tableTemplate = (table, index) => {
  let field = `table${index}`;
  let requestData = templateData[field];
  const tableRowTemplate = (rows, data) => {
    let arr = [];
    data.forEach((item) => {
      arr.push(rows);
    });
    return arr;
  };
  let data = JSON.parse(JSON.stringify(table));
  let arr = [];
  data.forEach((item) => {
    let bol = hasCaretPattern(JSON.parse(JSON.stringify(item.content)));
    if (bol) {
      let obj = item;
      let rows = tableRowTemplate(item.content, requestData);
      rows.forEach((row, key) => {
        // arr.push({ ...item, content: row });
        arr.push(fillRowData(JSON.parse(JSON.stringify({ ...obj, content: row })), requestData[key]));
      });
    } else {
      let obj = fillData(item);
      arr.push(obj);
    }
  });
  return arr.filter((item) => item);
};
const fillData = (e) => {
  let index = 0;
  if (e.type === 'table') {
    e.content = tableTemplate(e.content, index);
    index++;
  } else {
    if (Array.isArray(e.content)) {
      e.content.map((item) => {
        return fillData(item);
      });
    } else {
      e.text = renderTemplate(e.text || '', templateData);
    }
  }
  return e;
};

const insertText = (e) => {
  const editor = editorRef.value;
  editor.insertContent(
    {
      type: 'text',
      text: e.varName
    },
    {
      updateSelection: false
    }
  );
};
onMounted(async () => {
  getPrintTemplate(route.query.templateId).then((e) => {
    template.value = e.data;
    const editor = editorRef.value;
    let docData = JSON.parse(e.data.templateData || '{}');
    let data = fillData(docData);
    console.log(data);
    editor.setContent(JSON.parse(e.data.templateData || '{}'));
    // editor.setContent(data);
  });
  getBaseTemplateVariableList().then((e) => {
    fieldList.value = e.data;
  });
});
let obj1 = {};
</script>

<style scoped>
.title {
  width: 100%;
  line-height: 40px;
  font-size: 14px;
  color: #666;
  text-align: center;
}

.fieldList {
  width: 100%;
  height: calc(100vh - 50px - 34px - 40px);
  overflow-y: auto;

  .fieldItem {
    width: 80%;
    font-size: 12px;
    padding-left: 15px;
    color: #333;
    cursor: pointer;

    .btn {
      padding: 10px;

      &:hover {
        background-color: #eee;
        border-radius: 10px;
      }
    }
  }
}
</style>
<style>
.umo-footer {
  position: sticky;
  bottom: 0px;
}
</style>
