<template>
  <div class="gl-page-content-grey-full">
    <div class="content">
      <DragSplit :leftContentWidth="400">
        <template #left>
          <div class="page-content-left">
            <el-tree
              v-if="showTree"
              ref="libTreeRef"
              node-key="nodeKey"
              highlight-current
              lazy
              :props="props"
              :current-node-key="currentNodeKey"
              :load="loadMoreFun"
              @current-change="currentChangeFun"
            >
              <template #default="{ data }">
                <div class="custom-tree-node">
                  <el-icon class="icon-style" v-if="data.type != 3" :size="18"><Folder /></el-icon>
                  <el-icon class="icon-style" v-else :size="18"><Document /></el-icon>
                  <div class="name" :title="data.name">{{ data.name }}</div>
                  <div class="options">
                    <div class="edit" @click="openEditFun(data)">
                      <el-icon>
                        <EditPen />
                      </el-icon>
                    </div>
                    <div class="del" @click="deleteParamFun(dataType[data.type])">
                      <el-icon>
                        <Delete />
                      </el-icon>
                    </div>
                  </div>
                </div>
              </template>
            </el-tree>
          </div>
        </template>
        <template #right>
          <div class="page-content-right">
            <BaseTable
              ref="paramTableRef"
              tableName="PARAMETER_LIST"
              hidePagination
              :actionList="actionList"
            >
              <template #leftOptions>
                <div class="options">
                  <el-button
                    type="primary"
                    v-if="currentNode?.type === 1 || !currentNode?.type"
                    @click="openCreateFun('lib')"
                  >
                    新增参数库
                  </el-button>
                  <el-button
                    type="primary"
                    v-if="currentNode?.type === 1"
                    @click="openCreateFun('type')"
                  >
                    新增分类
                  </el-button>
                  <el-button
                    v-if="currentNode?.type === 2"
                    type="primary"
                    @click="openCreateFun('param')"
                  >
                    新增参数对象
                  </el-button>
                  <template v-if="currentNode?.type === 3">
                    <el-button type="primary" @click="openParamFun">新增参数</el-button>
                    <el-button
                      v-if="objFormatFun(newParamTableData) !== objFormatFun(paramTableData)"
                      type="primary"
                      @click="updateParamFun"
                    >
                      保存
                    </el-button>
                    <el-button
                      v-if="paramObjInfo.fileName"
                      @click="downloadFun(paramObjInfo.fileId)"
                    >
                      下载JSON文件
                    </el-button>
                  </template>
                  <el-button @click="infoShow = true">基本信息</el-button>
                </div>
              </template>
            </BaseTable>
          </div>
        </template>
      </DragSplit>
    </div>
    <el-drawer
      v-model="infoShow"
      :size="400"
      title="基本信息"
      :close-on-click-modal="false"
      @close="infoShow = false"
    >
      <div class="info-content">
        <el-descriptions class="info-content-descriptions" :column="1" label-width="100px" border>
          <el-descriptions-item label="所属库">
            {{ paramObjInfo?.parameterLibraryName }}
          </el-descriptions-item>
          <el-descriptions-item v-if="paramObjInfo?.parameterLibraryCategoryName" label="所属分类">
            {{ paramObjInfo?.parameterLibraryCategoryName }}
          </el-descriptions-item>
          <el-descriptions-item
            v-if="paramObjInfo?.parameterLibraryCategoryObjectName"
            label="对象名称"
          >
            {{ currentNode.name }}
          </el-descriptions-item>
          <el-descriptions-item label="创建时间">
            {{ currentNode.createTime }}
          </el-descriptions-item>
          <el-descriptions-item label="创建人">
            {{ currentNode.createName }}
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-drawer>
    <addParamLib
      v-if="showParamLibVisible"
      @close="showParamLibVisible = false"
      @createFun="createLibFun"
    />
    <addParamType
      v-if="showParamTypeVisible"
      @close="showParamTypeVisible = false"
      :lib-info="currentNode"
      @createFun="createLibTypeFun"
    />
    <addParamObject
      v-if="showParamObjVisible"
      @close="showParamObjVisible = false"
      :lib-type-info="currentNode"
      @createFun="creatLibParamObjFun"
    />
    <ApproveDel v-model="approveDelShow" :api="deleteSimulationParameterApi" :params="delParams" />
    <Edit v-model="editShow" :data="editData" @confirm="resetTreeFun" />
    <ParamDetail
      v-model="paramDetailShow"
      :data="paramData"
      @add="addParamFun"
      @edit="editParamFun"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { Document, Folder, EditPen, Delete } from '@element-plus/icons-vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import {
  getSimulationParameterTreeApi,
  addLibraryApi,
  addLibraryCategoryApi,
  getSimulationParameterLibraryCategoryObjectApi,
  addLibraryCategoryObjectApi,
  deleteSimulationParameterApi,
  updateSimulationParameterValuesApi,
} from '@/api/data/simulationParameterLibrary';
import addParamLib from './components/addParamLib.vue';
import addParamType from './components/addParamType.vue';
import addParamObject from './components/addParamObject.vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import ApproveDel from '@/components/common/approveDel/index.vue';
import Edit from './components/edit.vue';
import DragSplit from '@/components/common/dragSplit/index.vue';
import ParamDetail from './components/addParam.vue';
import { downloadFileById } from '@/utils/file';
import { cloneDeep } from 'lodash-es';

const currentNodeKey = ref<any>('');
const currentNode = ref<any>({});
const showParamLibVisible = ref(false);
const showParamTypeVisible = ref(false);
const showParamObjVisible = ref(false);
const showTree = ref(true);
const libTreeRef = ref();
const paramTableRef = ref();
const infoShow = ref(false);
const approveDelShow = ref(false);
const delParams = ref<any>({});
const editShow = ref(false);
const editData = ref<any>({});
const paramDetailShow = ref(false);
const paramData = ref<any>({});
const paramEditIndex = ref(0);
const paramTableData = ref<any>([]);
const newParamTableData = ref<any>([]);
const props = {
  label: 'label',
  children: 'children',
  isLeaf: 'leaf',
};

const dataType: any = {
  1: 'lib',
  2: 'type',
  3: 'param',
};

const actionList = ref([
  {
    title: '编辑',
    type: 'primary',
    click: (row: any, index: number) => {
      paramEditIndex.value = index;
      paramData.value = row;
      paramDetailShow.value = true;
    },
  },
  {
    title: '删除',
    type: 'danger',
    needConfirm: true,
    confirmTip: '确认删除参数吗？',
    click: (row: any, index: number) => {
      newParamTableData.value.splice(index, 1);
      paramTableRef.value.setDataFun(newParamTableData.value);
    },
  },
]);

const loadMoreFun = async (node: any, resolve: any) => {
  const listData: any = await getSimulationParameterTreeDAtaFun(node.data);
  return resolve(listData);
};

const getSimulationParameterTreeDAtaFun = async (data?: any) => {
  const param: any = {
    type: 1,
  };
  if (data?.type) {
    param.type = data.type;
  }
  if (data?.id) {
    param.id = data.id;
  }
  const res: any = await getSimulationParameterTreeApi(param);
  if (res && res.code === 200) {
    const result = res.data.map((item: any) => {
      const node: any = {
        ...item,
        nodeKey: item.id + '_' + item.type,
      };
      if (param.type === 1 && param.id) {
        node.libName = data.name;
        node.libId = data.id;
      }
      if (param.type === 2 && param.id) {
        node.typeName = data.name;
        node.typeId = data.id;
        node.libName = data.libName;
        node.libId = data.libId;
        node.leaf = true;
        node.isLeaf = true;
      }
      return node;
    });
    return result;
  }
};

const paramObjInfo = ref<any>({});

// 当前节点更改
const currentChangeFun = async (data: any) => {
  currentNodeKey.value = data.nodeKey;
  currentNode.value = data;
  paramTableRef.value.setDataFun([]);
  if (data.type === 3) {
    const res: any = await getSimulationParameterLibraryCategoryObjectApi({
      ObjectId: data.id,
    });
    if (res && res.code === 200) {
      paramObjInfo.value = res.data || [];
      paramTableRef.value.setDataFun(paramObjInfo.value.parameterJsonValue || []);
      paramTableData.value = paramObjInfo.value.parameterJsonValue || [];
      newParamTableData.value = cloneDeep(paramTableData.value);
      currentNode.value.fileId = res.data.fileId;
    }
  } else if (data.type === 2) {
    paramObjInfo.value = {
      parameterLibraryName: data.libName,
      parameterLibraryCategoryName: data.name,
    };
  } else if (data.type === 1) {
    paramObjInfo.value = {
      parameterLibraryName: data.name,
    };
  } else {
    paramObjInfo.value = {};
  }
};

const openEditFun = (data: any) => {
  editData.value = data;
  editShow.value = true;
};

const resetTreeFun = (data: any) => {
  const { id, type, modifyFileName } = data;
  const node = libTreeRef.value.getNode(`${id}_${type}`);
  node.data.name = modifyFileName;
};

const openCreateFun = (flag: any) => {
  if (flag === 'lib') {
    showParamLibVisible.value = true;
  }
  if (flag === 'type') {
    showParamTypeVisible.value = true;
  }
  if (flag === 'param') {
    showParamObjVisible.value = true;
  }
};

const createLibFun = async (data: any) => {
  const res: any = await addLibraryApi(data);
  if (res && res.code === 200) {
    ElMessage.success('新增参数库成功');
    const libList = await getSimulationParameterTreeDAtaFun();
    if (libList.length === 1) {
      showTree.value = false;
    } else {
      libTreeRef.value.insertAfter(libList.at(-1), libList[libList.length - 2].nodeKey);
    }
  }
  showTree.value = true;
  showParamLibVisible.value = false;
  return;
};

const createLibTypeFun = async (data: any) => {
  const res: any = await addLibraryCategoryApi(data);
  if (res && res.code === 200) {
    ElMessage.success('新增参数分类成功');
    const list = await getSimulationParameterTreeDAtaFun(currentNode.value);
    const node = list.find((item: any) => {
      return item.name === data.parameterLibraryCategoryName;
    });
    libTreeRef.value.append(node, currentNode.value.nodeKey);
  }
  showParamTypeVisible.value = false;
};

const creatLibParamObjFun = async (data: any) => {
  const res: any = await addLibraryCategoryObjectApi({
    parameterLibraryId: data.parameterLibraryId,
    parameterLibraryCategoryId: data.parameterLibraryCategoryId,
    parameterLibraryCategoryObjectName: data.parameterLibraryCategoryObjectName,
    fileName: data.fileName,
    file: data.file,
    templateId: data.templateId,
    templateName: data.templateName,
  });

  if (res && res.code === 200) {
    ElMessage.success('操作成功');
    const list = await getSimulationParameterTreeDAtaFun(currentNode.value);
    const node = list.find((item: any) => {
      return item.name === data.parameterLibraryCategoryObjectName;
    });
    libTreeRef.value.append(node, currentNode.value.nodeKey);
  }
  showParamObjVisible.value = false;
};

const deleteParamFun = (flag: any) => {
  if (flag === 'param') {
    delParams.value = {
      type: currentNode.value.type,
      id: currentNode.value.id,
    };
    approveDelShow.value = true;
    return;
  }
  ElMessageBox.confirm(
    `确认要删除这个${flag === 'lib' ? '参数库' : flag === 'type' ? '参数库分类' : '参数对象'}吗?`,
    '警告',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(async () => {
    const res: any = await deleteSimulationParameterApi({
      type: currentNode.value.type,
      id: currentNode.value.id,
    });
    if (res && res.code === 200) {
      ElMessage.success('删除成功！');
      libTreeRef.value.remove(currentNode.value.nodeKey);
      currentNode.value = {};
      paramObjInfo.value = '';
    }
  });
};

const updateParamFun = () => {
  const params = {
    fileId: currentNode.value.fileId,
    parameterList: newParamTableData.value,
  };
  updateSimulationParameterValuesApi(params).then((res: any) => {
    if (res.code === 200) {
      ElMessage.success('操作成功');
      currentChangeFun(currentNode.value);
    }
  });
};

const openParamFun = () => {
  paramData.value = {};
  paramDetailShow.value = true;
};

const addParamFun = (data: any) => {
  newParamTableData.value.unshift(data);
  paramTableRef.value.setDataFun(newParamTableData.value);
};

const editParamFun = (data: any) => {
  newParamTableData.value[paramEditIndex.value] = data;
  paramTableRef.value.setDataFun(newParamTableData.value);
};

const downloadFun = (fileId: number) => {
  downloadFileById(fileId);
};

const objFormatFun = (data: any) => {
  const val = cloneDeep(data);
  const formatData = val.map((item: any) => {
    delete item._X_ROW_KEY;
    return item;
  });
  return JSON.stringify(formatData);
};
</script>

<style lang="scss" scoped>
.gl-page-content-grey-full {
  .content {
    height: 100%;
    width: 100%;
    display: flex;
    .page-content-left {
      padding: 10px;
      width: 100%;
      height: 100%;
      background-color: var(--el-bg-color);
      .custom-tree-node {
        display: flex;
        align-items: center;
        width: 100%;
        .icon-style {
          color: var(--el-color-primary);
          margin-right: 5px;
        }
        .name {
          width: 0;
          flex: 1;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .options {
          display: flex;
          align-items: center;
          justify-content: flex-end;
          padding-right: 5px;
          .edit {
            margin-left: 12px;
            color: var(--el-color-primary);
          }
          .del {
            margin-left: 12px;
            color: var(--el-color-danger);
          }
        }
      }
    }
    .page-content-right {
      flex: 1;
      padding: 16px;
      background-color: var(--el-bg-color);
      height: 100%;
      .options {
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }
}
.pinfo-content {
  width: 100%;
  height: 100%;
  .info-content-descriptions {
    margin-top: var(--margin-small);
  }
}
</style>
