<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"
        >
          <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="(grid, gridIndex) in paragraph.children" :key="gridIndex" class="grid">
              <div v-if="!(modeType === 'input' && !grid.key)" class="add-title">
                <el-input
                  v-model="grid[modeKey]"
                  :placeholder="placeholderFun('请输入小节标题')"
                  clearable
                  :disabled="preview"
                />
              </div>
              <template v-for="(unit, unitIndex) in grid.children" :key="unitIndex">
                <div v-if="unit.type === 'title'" class="unit title">
                  <div v-if="modeType === 'input' || preview">{{ unit.value }}</div>
                  <el-input
                    v-else
                    v-model="unit.value"
                    type="input"
                    placeholder="请输入标题"
                    clearable
                  />
                  <div class="del-btn" @click="delFun(paragraphIndex, gridIndex, unitIndex)">
                    <el-icon :size="22"><DeleteFilled /></el-icon>
                  </div>
                </div>
                <div v-if="unit.type === 'text'" class="unit">
                  <el-input
                    v-model="unit[modeKey]"
                    type="textarea"
                    :placeholder="placeholderFun('请输入文本')"
                    :disabled="preview"
                  />
                  <div class="del-btn" @click="delFun(paragraphIndex, gridIndex, unitIndex)">
                    <el-icon :size="22"><DeleteFilled /></el-icon>
                  </div>
                </div>
                <div v-else-if="unit.type === 'form'" class="unit">
                  <Form v-model:value="unit.children" :mode="modeType" :disabled="preview" />
                  <div class="del-btn" @click="delFun(paragraphIndex, gridIndex, unitIndex)">
                    <el-icon :size="22"><DeleteFilled /></el-icon>
                  </div>
                </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"
                  />
                  <div class="del-btn" @click="delFun(paragraphIndex, gridIndex, unitIndex)">
                    <el-icon :size="22"><DeleteFilled /></el-icon>
                  </div>
                </div>
                <div v-else-if="unit.type === 'img'" class="unit">
                  <Img
                    v-model:keyValue="unit.key"
                    v-model:value="unit.value"
                    :mode="modeType"
                    :disabled="preview"
                  />
                  <div class="del-btn" @click="delFun(paragraphIndex, gridIndex, unitIndex)">
                    <el-icon :size="22"><DeleteFilled /></el-icon>
                  </div>
                </div>
              </template>
              <div class="add-content">
                <el-button
                  :icon="Notification"
                  type="primary"
                  @click="addFun('title', paragraphIndex, gridIndex)"
                >
                  新增标题
                </el-button>
                <el-button
                  :icon="Edit"
                  type="primary"
                  @click="addFun('text', paragraphIndex, gridIndex)"
                >
                  新增文本
                </el-button>
                <el-button
                  :icon="Document"
                  type="primary"
                  @click="addFun('form', paragraphIndex, gridIndex)"
                >
                  新增表单
                </el-button>
                <el-button
                  :icon="Grid"
                  type="primary"
                  @click="addFun('table', paragraphIndex, gridIndex)"
                >
                  新增表格
                </el-button>
                <el-button
                  :icon="Picture"
                  type="primary"
                  @click="addFun('img', paragraphIndex, gridIndex)"
                >
                  新增图片
                </el-button>
              </div>
              <div class="del-btn" @click="delFun(paragraphIndex, gridIndex)">
                <el-icon :size="22"><DeleteFilled /></el-icon>
              </div>
            </div>
            <div class="add-content">
              <el-button :icon="FullScreen" type="primary" @click="addFun('grid', paragraphIndex)">
                新增小节
              </el-button>
            </div>
          </div>
          <div class="del-btn" @click="delFun(paragraphIndex)">
            <el-icon :size="22"><DeleteFilled /></el-icon>
          </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,
  DeleteFilled,
} 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 { cloneDeep } from 'lodash-es';

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, gridIndex?: any) => {
  if (type === 'paragraph') {
    documentData.value.push(createDataFun('paragraph'));
  }
  if (type === 'grid') {
    documentData.value[paragraphIndex].children.push(createDataFun('grid'));
  }
  if (type === 'title' && gridIndex >= 0) {
    documentData.value[paragraphIndex].children[gridIndex].children.push(createDataFun('title'));
  }
  if (type === 'text' && gridIndex >= 0) {
    documentData.value[paragraphIndex].children[gridIndex].children.push(createDataFun('text'));
  }
  if (type === 'form' && gridIndex >= 0) {
    documentData.value[paragraphIndex].children[gridIndex].children.push(createDataFun('form'));
  }
  if (type === 'table' && gridIndex >= 0) {
    documentData.value[paragraphIndex].children[gridIndex].children.push(createDataFun('table'));
  }
  if (type === 'img' && gridIndex >= 0) {
    documentData.value[paragraphIndex].children[gridIndex].children.push(createDataFun('img'));
  }
};

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

const createDataFun = (type: string) => {
  return {
    type,
    key: '',
    value: '',
    children: [],
  };
};

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,
    });
    paragraph.children.forEach((grid: any) => {
      build.push({
        type: grid.type,
        key: grid.key,
        value: grid.value,
      });
      grid.children.forEach((unit: any) => {
        if (unit.type === 'form') {
          unit.children.forEach((item: any) => {
            build.push({
              type: 'text',
              key: item.key,
              value: item.value,
            });
          });
        } else {
          const unitData: any = {
            type: unit.type,
            key: unit.key,
            value: unit.value,
          };
          if (unit.type === 'table') {
            unitData.head = unit.head.map((i: any) => i.title);
          }
          build.push(unitData);
        }
      });
    });
  });
  return build;
};

defineExpose({
  getFormatDataFun,
});
</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 10px 10px 30px;
      overflow-y: auto;
      &.input-mode {
        .add-content {
          display: none !important;
        }
        .del-btn {
          display: none !important;
        }
      }
      .paragraph {
        position: relative;
        padding: 10px;
        margin-bottom: 10px;
        border-radius: 4px;
        border: dashed 2px var(--el-border-color);
        &:hover {
          > .del-btn {
            opacity: 1;
          }
        }
        .content {
          border-radius: 4px;
          padding: 10px;
          border: solid 1px var(--el-border-color);
          &:hover {
            .add-content {
              opacity: 1;
            }
          }
          .add-content {
            opacity: 0;
          }
          .grid {
            position: relative;
            background-color: var(--el-border-color-lighter);
            border-radius: 4px;
            margin-bottom: 10px;
            padding: 10px;
            &:hover {
              .add-content {
                opacity: 1;
              }
              > .del-btn {
                opacity: 1;
              }
            }
            .unit {
              position: relative;
              margin-bottom: 10px;
              &.title {
                width: 300px;
              }
              &:hover {
                .del-btn {
                  opacity: 1;
                }
              }
            }
            .add-content {
              opacity: 0;
            }
          }
        }
      }
    }
  }
  .del-btn {
    opacity: 0;
    position: absolute;
    top: 5px;
    left: -29px;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--el-color-danger);
    background-color: var(--el-bg-color);
    border-radius: 4px 0 0 4px;
    border: solid 1px var(--el-border-color);
    border-right: 0;
    z-index: 1;
    cursor: pointer;
  }
  .add-title {
    width: 300px;
    margin-bottom: 10px;
  }
  .add-content {
    margin-top: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
