<template>
  <div class="comp-document-edit">
    <div class="comp-content">
      <div class="preview-content">
        <div class="title">模版预览</div>
        <div class="tip">这是您将要生成的文档模版样式</div>
        <div class="preview">
          <KkfileView :fileId="fileId" />
        </div>
      </div>
      <div :class="['edit-content', { 'input-mode': modeType === 'input' }]">
        <div
          v-for="(paragraph, paragraphIndex) in documentData"
          :key="paragraphIndex"
          class="paragraph"
        >
          <Toper
            title="章节"
            :btns="['del']"
            :disabled="modeType === 'input'"
            @del="delFun(paragraphIndex)"
          />
          <!-- <div v-if="!(modeType === 'input' && !paragraph.key)" class="add-title">
            <el-input
              v-model="paragraph[modeKey]"
              :placeholder="placeholderFun('请输入章节标题')"
              clearable
              :disabled="preview"
            />
          </div> -->
          <div class="content">
            <div
              v-for="(section, sectionIndex) in paragraph.children"
              :key="sectionIndex"
              :class="['section', { empty: section.type === 'empty' }]"
            >
              <Toper
                :title="section.type === 'section' ? '小节' : ''"
                :btns="['del']"
                :disabled="modeType === 'input'"
                @del="delFun(paragraphIndex, sectionIndex)"
              />
              <!-- <div v-if="!(modeType === 'input' && !section.key)" class="add-title">
                <el-input
                  v-model="section[modeKey]"
                  :placeholder="placeholderFun('请输入小节标题')"
                  clearable
                  :disabled="preview"
                />
              </div> -->
              <template v-for="(unit, unitIndex) in section.children" :key="unitIndex">
                <div v-if="unit.type === 'title'" class="unit">
                  <div v-if="modeType === 'input' || preview" class="title-name-simple">
                    {{ unit.value }}
                  </div>
                  <div v-else class="title-name">
                    <Toper
                      title="标题"
                      :btns="['del']"
                      :disabled="modeType === 'input'"
                      @del="delFun(paragraphIndex, sectionIndex, unitIndex)"
                    />
                    <el-input
                      v-model="unit.value"
                      type="input"
                      placeholder="请输入标题"
                      clearable
                    />
                  </div>
                </div>
                <div v-if="unit.type === 'text'" class="unit">
                  <div class="textarea">
                    <Toper
                      title="文本"
                      :btns="['del']"
                      :disabled="modeType === 'input'"
                      @del="delFun(paragraphIndex, sectionIndex, unitIndex)"
                    />
                    <el-input
                      v-model="unit[modeKey]"
                      type="textarea"
                      :placeholder="placeholderFun('请输入文本')"
                      :disabled="preview"
                    />
                  </div>
                </div>
                <div v-else-if="unit.type === 'form'" class="unit">
                  <Form
                    v-model:value="unit.children"
                    :mode="modeType"
                    :disabled="preview"
                    @del="delFun(paragraphIndex, sectionIndex, unitIndex)"
                  />
                </div>
                <div v-else-if="unit.type === 'table'" class="unit">
                  <Table
                    v-model:keyValue="unit.key"
                    v-model:value="unit.value"
                    v-model:head="unit.head"
                    :mode="modeType"
                    :disabled="preview"
                    @del="delFun(paragraphIndex, sectionIndex, unitIndex)"
                  />
                </div>
                <div v-else-if="unit.type === 'img'" class="unit">
                  <Img
                    v-model:keyValue="unit.key"
                    v-model:value="unit.value"
                    v-model:params="unit.params"
                    :mode="modeType"
                    :disabled="preview"
                    @del="delFun(paragraphIndex, sectionIndex, unitIndex)"
                  />
                </div>
              </template>
              <div class="add-content">
                <el-button
                  :icon="Notification"
                  type="primary"
                  @click="addFun('title', paragraphIndex, sectionIndex)"
                >
                  新增标题
                </el-button>
                <el-button
                  :icon="Edit"
                  type="primary"
                  @click="addFun('text', paragraphIndex, sectionIndex)"
                >
                  新增文本
                </el-button>
                <el-button
                  :icon="Document"
                  type="primary"
                  @click="addFun('form', paragraphIndex, sectionIndex)"
                >
                  新增表单
                </el-button>
                <el-button
                  :icon="Grid"
                  type="primary"
                  @click="addFun('table', paragraphIndex, sectionIndex)"
                >
                  新增表格
                </el-button>
                <el-button
                  :icon="Picture"
                  type="primary"
                  @click="addFun('img', paragraphIndex, sectionIndex)"
                >
                  新增图片
                </el-button>
              </div>
            </div>
            <div class="add-content">
              <el-button :icon="FullScreen" type="primary" @click="addFun('empty', paragraphIndex)">
                新增区块
              </el-button>
              <el-button
                :icon="DocumentCopy"
                type="primary"
                @click="addFun('section', paragraphIndex)"
              >
                新增小节
              </el-button>
            </div>
          </div>
        </div>
        <div class="add-content">
          <el-button :icon="DocumentAdd" type="primary" @click="addFun('paragraph', -1)">
            新增章节
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import {
  FullScreen,
  Notification,
  Edit,
  Grid,
  Document,
  Picture,
  DocumentAdd,
  DocumentCopy,
} from '@element-plus/icons-vue';
import Form from './form.vue';
import Table from './table.vue';
import Img from './img.vue';
import KkfileView from '@/components/common/filePreview/kkfileView.vue';
import Toper from './toper.vue';
import { cloneDeep } from 'lodash-es';
import { ElMessage } from 'element-plus';

interface Props {
  data: any;
  valueList?: any;
  fileId: any;
  mode: string;
  preview?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  data: [],
  valueList: [],
  fileId: '',
  mode: 'input', // input输入模式 edit编辑模板模式
  preview: false,
});

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

const modeType = ref('edit');
const modeKey = ref('key');
const documentData = ref<any>([]);

watch(
  () => props.mode,
  (val: any) => {
    if (val === 'edit') {
      modeType.value = 'edit';
      modeKey.value = 'key';
    } else {
      modeType.value = 'input';
      modeKey.value = 'value';
    }
  },
  { deep: true, immediate: true }
);

watch(
  () => props.data,
  (val: any) => {
    if (val) {
      documentData.value = val;
    }
  },
  { deep: true, immediate: true }
);

watch(
  () => documentData.value,
  (val: any) => {
    emit('update:data', val);
  },
  { deep: true }
);

const formatDataFun = (data: any) => {
  data.forEach((item: any) => {
    const matchData = props.valueList?.find((i: any) => i.key === item.key);
    if (item.key && matchData) {
      // 更具key值，将历史数据的value赋值给模板
      item.value = matchData.value;
    }
    if (item.children?.length > 0) {
      formatDataFun(item.children);
    }
  });
};

watch(
  () => props.valueList,
  () => {
    const formatData = cloneDeep(props.data);
    formatDataFun(formatData);
    emit('update:data', formatData);
  },
  { deep: true, immediate: true }
);

const addFun = (type: string, paragraphIndex: any, sectionIndex?: any) => {
  if (type === 'paragraph') {
    documentData.value.push(createDataFun('paragraph'));
  }
  if (type === 'empty') {
    documentData.value[paragraphIndex].children.push(createDataFun('empty'));
  }
  if (type === 'section') {
    documentData.value[paragraphIndex].children.push(createDataFun('section'));
  }
  if (type === 'title' && sectionIndex >= 0) {
    documentData.value[paragraphIndex].children[sectionIndex].children.push(createDataFun('title'));
  }
  if (type === 'text' && sectionIndex >= 0) {
    documentData.value[paragraphIndex].children[sectionIndex].children.push(createDataFun('text'));
  }
  if (type === 'form' && sectionIndex >= 0) {
    documentData.value[paragraphIndex].children[sectionIndex].children.push(createDataFun('form'));
  }
  if (type === 'table' && sectionIndex >= 0) {
    documentData.value[paragraphIndex].children[sectionIndex].children.push(createDataFun('table'));
  }
  if (type === 'img' && sectionIndex >= 0) {
    documentData.value[paragraphIndex].children[sectionIndex].children.push(createDataFun('img'));
  }
};

const delFun = (paragraphIndex: any, sectionIndex?: any, unitIndex?: any) => {
  if (paragraphIndex >= 0) {
    if (sectionIndex >= 0) {
      if (unitIndex >= 0) {
        documentData.value[paragraphIndex].children[sectionIndex].children.splice(unitIndex, 1);
      } else {
        documentData.value[paragraphIndex].children.splice(sectionIndex, 1);
      }
    } else {
      documentData.value.splice(paragraphIndex, 1);
    }
  }
};

const createDataFun = (type: string) => {
  const data: any = {
    type, // 类型
    key: '', // 报告生成对应key
    value: '', // 内容
    params: {}, // 其他参数
    children: [], // 子节点
  };
  if (type === 'paragraph') {
    // 创建段落的时候默认添加一个empty
    data.children.push({
      type: 'empty', // 类型
      key: '', // 报告生成对应key
      value: '', // 内容
      params: {}, // 其他参数
      children: [], // 子节点
    });
  }
  return data;
};

const placeholderFun = (text: string) => {
  return `${text}${modeKey.value === 'key' ? 'key' : ''}`;
};

const getFormatDataFun = () => {
  const build: any = [];
  documentData.value.forEach((paragraph: any) => {
    build.push({
      type: paragraph.type,
      key: paragraph.key,
      value: paragraph.value,
      params: paragraph.params,
    });
    paragraph.children.forEach((section: any) => {
      build.push({
        type: section.type,
        key: section.key,
        value: section.value,
        params: section.params,
      });
      section.children.forEach((unit: any) => {
        if (unit.type === 'form') {
          unit.children.forEach((item: any) => {
            build.push({
              type: 'text',
              key: item.key,
              value: item.value,
              params: item.params,
            });
          });
        } else {
          const unitData: any = {
            type: unit.type,
            key: unit.key,
            value: unit.value,
            params: unit.params,
          };
          if (unit.type === 'table') {
            unitData.head = unit.head.map((i: any) => i.title);
          }
          build.push(unitData);
        }
      });
    });
  });
  return build;
};

const checkKeysFun = () => {
  const dataList = getFormatDataFun();
  const keys: any = [];
  let repeatKey = '';
  dataList.some((item: any) => {
    if (item.key) {
      if (keys.includes(item.key)) {
        repeatKey = item.key;
        return true;
      } else {
        keys.push(item.key);
      }
    }
  });
  if (repeatKey) {
    ElMessage.warning(`${repeatKey}重复，请更改后再提交`);
    return false;
  } else {
    return true;
  }
};

defineExpose({
  getFormatDataFun,
  checkKeysFun,
});
</script>

<style lang="scss" scoped>
.comp-document-edit {
  width: 100%;
  height: 100%;
  background-color: var(--el-bg-color);
  .comp-content {
    width: 100%;
    height: 100%;
    display: flex;
    .preview-content {
      width: 50%;
      height: 100%;
      padding: 10px;
      .title {
        color: var(--el-text-color-primary);
        font-size: 16px;
        line-height: 30px;
      }
      .tip {
        color: var(--el-text-color-secondary);
        font-size: 14px;
        line-height: 20px;
      }
      .preview {
        height: calc(100% - 50px);
      }
    }
    .edit-content {
      width: 50%;
      height: 100%;
      padding: 10px;
      overflow-y: auto;
      &.input-mode {
        .add-content {
          display: none !important;
        }
        .section {
          &.empty {
            padding: 2px !important;
          }
        }
      }
      .paragraph {
        position: relative;
        padding: 20px 10px 10px;
        margin-bottom: 10px;
        border-radius: 4px;
        border: solid 1px var(--el-border-color);
        .content {
          border-radius: 4px;
          padding: 10px;
          background-color: var(--el-border-color-extra-light);
          &:hover {
            .add-content {
              opacity: 1;
            }
          }
          .add-content {
            opacity: 0;
          }
          .section {
            position: relative;
            padding: 20px 10px 10px;
            border-radius: 4px;
            margin-bottom: 10px;
            border: solid 1px var(--el-border-color);
            background-color: var(--el-bg-color);
            &.empty {
              padding: 20px 2px 10px;
              border: none;
            }
            &:hover {
              .add-content {
                opacity: 1;
              }
            }
            .unit {
              position: relative;
              margin-bottom: 10px;
              .title-name {
                position: relative;
                padding: 20px 10px 10px;
                border-radius: 4px;
                border: solid 1px var(--el-border-color);
              }
              .title-name-simple {
                padding: 0 10px;
                font-size: 14px;
                color: var(--el-text-color-primary);
              }
              .textarea {
                position: relative;
                padding: 20px 10px 10px;
                border-radius: 4px;
                border: solid 1px var(--el-border-color);
              }
            }
            .add-content {
              opacity: 0;
            }
          }
        }
      }
    }
  }
  .add-title {
    width: 300px;
    margin-bottom: 10px;
  }
  .add-content {
    margin-top: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
