<template>
  <div
    class="mainContentBox"
    style="padding: 0; box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1)"
  >
    <div class="header">
      <div class="title">绑定工序</div>
      <el-button :icon="Back" size="small" @click="back">返回</el-button>
    </div>
    <div class="binContainer">
      <div class="processTree">
        <el-scrollbar>
          <el-collapse v-model="activeNames">
            <el-collapse-item
              v-for="(pProcess, pIndex) in list1"
              :key="pProcess.workSection"
              :name="pIndex"
            >
              <template #title>
                <div class="title2">
                  {{ getNameByDictType(pProcess.workSection) }}
                </div>
              </template>
              <div class="treeChild">
                <div
                  class="childItem"
                  v-for="(item, index) in pProcess?.baseOperationList"
                  :key="index"
                  :draggable="!editStatus && usableStatus"
                  @dragstart="
                    onDragStart($event, nodeType, item.operationName, item)
                  "
                >
                  {{ item.operationName }}
                </div>
              </div>
            </el-collapse-item>
          </el-collapse>
        </el-scrollbar>
      </div>
      <div
        class="flowBox"
        id="flowBox"
        style="height: 100%; width: 100%; overflow: hidden"
      >
        <div class="dnd-flow" @drop="onDrop">
          <VueFlow
            v-model:nodes="flowData.nodes"
            v-model:edges="flowData.edges"
            :apply-default="!editStatus && usableStatus"
            @dragover="onDragOver"
            @dragleave="onDragLeave"
            @node-click="nodeClick($event)"
            @edge-click="edgeClick($event)"
          >
            <MiniMap style="background-color: grey" />
            <template #edge-custom="props">
              <CustomConnectionLine v-bind="props" />
            </template>
            <template #connection-line="props">
              <CustomConnectionLine v-bind="props" />
            </template>
            <template #node-custom="props">
              <CustomNode v-bind="props" />
            </template>
            <DropzoneBackground
              :style="{
                backgroundColor: isDragOver ? '#e7f3ff' : 'transparent',
                transition: 'background-color 0.2s ease',
              }"
            >
              <p v-if="isDragOver">拖拽中</p>
            </DropzoneBackground>
          </VueFlow>

          <div
            :style="{
              width: flowBoxW - 20 + 'px',
              height: flowBoxH - 20 + 'px',
            }"
          ></div>
        </div>
      </div>
      <div class="detailInfo">
        <el-scrollbar>
          <div class="opBox">
            <el-button type="primary" @click="changeEditStatus">{{
              !editStatus ? "切换为工序信息编辑模式" : "切换为工序路线编辑模式"
            }}</el-button>

            <el-button @click="getPng">导出流程图 </el-button>
          </div>

          <!-- 工艺路线编辑模式 -->
          <div v-if="!editStatus && usableStatus">
            <div class="btns">
              <el-button type="primary" @click="saveFlow">保存</el-button>
              <el-button type="danger" v-if="cancelStatus" @click="cancelFlow"
                >取消</el-button
              >
              <el-button
                type="info"
                v-if="selectNode || selectLine"
                @click="deleteFlow"
                >删除</el-button
              >
            </div>
          </div>
          <!-- 工序信息编辑模式 -->
          <div v-else>
            <div v-if="currentProcess.id">
              <avue-form
                ref="formRef"
                :option="formOption"
                v-model="currentProcess"
                :key="avueKey"
                style="padding: 10px; background-color: transparent"
              >
                <template #tbomUrl>
                  <FilesUpload
                    v-model:src="currentProcess.tbomUrl"
                    :show-tip="false"
                  />
                </template>
                <template #customFieldName>
                  <el-select
                    v-model="customFieldNameValues"
                    multiple
                    default-first-option
                    :reserve-keyword="false"
                    placeholder="请选择名称"
                  >
                    <el-option
                      v-for="item in customFieldOptions"
                      :key="item.value"
                      :label="item.value"
                      :value="item.value"
                    />
                  </el-select>
                </template>
              </avue-form>
              <div class="btns">
                <el-tooltip
                  class="box-item"
                  effect="dark"
                  content="会同时保存现线路情况，请确认好变更"
                  placement="bottom"
                >
                  <el-button type="primary" @click="saveInfo"
                    >保存工序详情</el-button
                  >
                </el-tooltip>
                <el-button type="danger" @click="cancelInfo"
                  >重置该工序详情</el-button
                >
              </div>
              <div class="editProcces">
                <el-button type="primary" @click="editProComponent"
                  >编辑工序组件</el-button
                >
              </div>
            </div>
            <div v-else-if="!usableStatus" class="tipContent">
              已绑定工序不可编辑线路情况
            </div>
            <div v-else class="tipContent">请选择工序</div>
          </div>
        </el-scrollbar>
      </div>
    </div>
  </div>
</template>

<script setup>
import {
  Back,
  Download,
  Document,
  Delete,
  Bottom,
  Grid,
} from "@element-plus/icons-vue";
import _ from "lodash-es";
import { VueFlow, useVueFlow } from "@vue-flow/core";
import DropzoneBackground from "./components/DropzoneBackground/index.vue";
import CustomConnectionLine from "./components/CustomConnectionLine/index.vue";
import CustomNode from "./components/CustomNode/index.vue";
import useDragAndDrop from "@/hooks/useDnD.js";
import { MiniMap } from "@vue-flow/minimap";
import { processTreeList } from "@/api/craft/process/index";
import { useCommonStoreHook, useDictionaryStore } from "@/store";
import {
  processesByRouteId,
  saveProcessInRoute,
  updateProcess,
} from "@/api/craft/route/index";
import { formOption } from "./bindConfig";
import { ElMessage } from "element-plus";
import { useScreenshot } from "./screenshot.ts";
defineOptions({
  name: "bindProcess/:id/:prodtCode",
});

const { capture } = useScreenshot();
const instance = useVueFlow();
const { onConnect, addEdges, vueFlowRef, onEdgeUpdateEnd, applyEdgeChanges } =
  instance;
const { onDragOver, onDrop, onDragLeave, isDragOver, onDragStart } =
  useDragAndDrop();
const flowData = ref({ edges: [], nodes: [] });
const flowDataCopy = ref({ edges: [], nodes: [] });
const currentProcess = ref({});
const selectNode = ref(null);
const selectLine = ref(null);
//true为可编辑线路
const usableStatus = ref(true);
provide("selectNode", selectNode);
provide("currentProcess", currentProcess);
provide("selectLine", selectLine);
const edgeClick = (event) => {
  if (usableStatus.value == false && !editStatus.value) return;
  if (!editStatus.value) {
    selectLine.value = event.edge;
    selectNode.value = null;
  }
};

// 自定义工序项目字段名称相关方法
const customFieldNameValues = ref([]);
const customFieldOptions = ref([]);
function isJSON(str) {
  if (typeof str !== "string") {
    return false;
  }

  try {
    JSON.parse(str);
    return true;
  } catch (e) {
    return false;
  }
}
const avueKey = ref(false);
const nodeClick = (event) => {
  if (usableStatus.value == false && !editStatus.value) return;
  if (!editStatus.value) {
    selectNode.value = event.node;
  } else {
    currentProcess.value = {};
    //让组件重新加载
    avueKey.value = !avueKey.value;
    currentProcess.value = event.node;

    // 设置自定义字段名称的选项内容等
    if (
      event.node.customFieldName &&
      isJSON(event.node.customFieldName) &&
      JSON.parse(event.node.customFieldName).length > 0
    ) {
      customFieldOptions.value = JSON.parse(event.node.customFieldName);
      customFieldNameValues.value = customFieldOptions.value
        .filter((item) => {
          return item.isSelected;
        })
        .map((item) => item.value);
    }
  }
};
//当使用回退时清空选择的node

const handleKeydown = () => {
  if (selectNode.value != null) {
    selectNode.value = null;
  }
  if (selectLine.value != null) {
    selectLine.value = null;
  }
};
onConnect(addEdges);
const getPng = () => {
  if (!vueFlowRef.value) {
    console.warn("VueFlow element not found");
    return;
  }
  capture(vueFlowRef.value, { shouldDownload: true });
};
const nodeType = ref("custom");
const editStatus = ref(false);
provide("editStatus", editStatus);
const changeEditStatus = () => {
  editStatus.value = !editStatus.value;
  if (editStatus.value == false) {
    currentProcess.value = {};
  } else {
    selectNode.value = null;
  }
};
const router = useRouter();
const route = useRoute();
// 数据字典相关
const { dicts } = useDictionaryStore();
//获取画布盒子具体长宽
const flowBoxH = ref(null);
const flowBoxW = ref(null);
const flowBoxScreen = () => {
  const flowBox = document.getElementById("flowBox");
  flowBoxH.value = flowBox.clientHeight;
  flowBoxW.value = flowBox.clientWidth;
};
// 顶部====================
const back = () => {
  router.back();
};

const download = () => {};

// 左侧工序树====================
const activeNames = ref([0]);
const list1 = ref([]);

// 保存中间的工序列表
const saveFlow = async () => {
  const { code } = await saveProcessInRoute({
    processRouteId: route.fullPath.split("/")[4],
    routeData: JSON.stringify({ ...flowData.value }),
  });
  if (code == "200") {
    ElMessage.success("保存成功");
  }
  loadProcessesFlow();
};
const cancelFlow = () => {
  flowData.value = JSON.parse(flowDataCopy.value);
  if (selectNode.value != null) {
    selectNode.value = null;
  }
  if (selectLine.value != null) {
    selectLine.value = null;
  }
};
const deleteFlow = () => {
  if (selectNode.value != null) {
    flowData.value.nodes.forEach((item, index) => {
      if (item.id == selectNode.value.id) {
        flowData.value.nodes.splice(index, 1);
      }
    });
  }
  if (selectLine.value != null) {
    flowData.value.edges.forEach((item, index) => {
      if (item.id == selectLine.value.id) {
        flowData.value.edges.splice(index, 1);
      }
    });
  }
  selectNode.value = null;
  selectLine.value = null;
  ElMessage.success("删除成功");
};

const saveInfo = async () => {
  // 处理currentProcess的自定义对象名称字段，如果customFieldNameValues在customFieldOptions中存在，则设置isSelected为true，否则设置为false,最后转为json
  const customFieldArr = [];
  customFieldOptions.value.forEach((item) => {
    let obj = {
      value: item.value,
      isSelected: customFieldNameValues.value.includes(item.value),
    };
    customFieldArr.push(obj);
  });

  currentProcess.value.customFieldName = JSON.stringify(customFieldArr);

  flowData.value.nodes.forEach((item, index) => {
    if (item.id == currentProcess.value.id) {
      flowData.value.nodes[index] = currentProcess.value;
    }
  });
  saveFlow();
  currentProcess.value = {};
};
const cancelInfo = () => {
  flowData.value.nodes.forEach((item, index) => {
    if (item.id == currentProcess.value.id) {
      currentProcess.value = flowData.value.nodes[index];
    }
  });
};
const loadTreeData = () => {
  processTreeList().then((res) => {
    list1.value = res.data ?? [];
  });
};
const cancelStatus = ref(true);
//通过id获取现存储信息
const loadProcessesFlow = async () => {
  const res = await processesByRouteId(route.fullPath.split("/")[4]);
  if (res.data) {
    if (res.data.routeData && res.data.routeData != "") {
      flowData.value = JSON.parse(res.data.routeData);
      flowDataCopy.value = res.data.routeData;
      cancelStatus.value = true;
      if (res.data.usable == 1) {
        usableStatus.value = false;
      }
    } else {
      cancelStatus.value = false;
    }
  } else {
    flowDataCopy.value = JSON.stringify(flowData.value);
  }
};

const formRef = ref(null);
const reset = () => {
  currentProcess.value = {};
  editStatus.value = false;
};
const editProComponent = async () => {
  router.push({
    path: `/base/craftManagement/processCom/${currentProcess.value.operationId}/${route.fullPath.split("/")[5]}/${route.fullPath.split("/")[4]}`,
  });
};

// 全局=======

onMounted(() => {
  loadTreeData();
  loadProcessesFlow();
  flowBoxScreen();
  window.addEventListener("keydown", handleKeydown);
});
onUnmounted(() => {
  window.removeEventListener("keydown", handleKeydown);
});
const getNameByDictType = (dictValue) => {
  let str = "";
  dicts?.workshop_section?.forEach((element) => {
    if (element?.dictValue === dictValue) {
      str = element?.dictLabel ?? "===";
    }
  });
  return str;
};

watch(
  () => flowData.value.edges,
  () => {
    flowData.value.edges.forEach((item) => {
      item.type = "custom";
    });
  }
);
</script>

<style lang="scss" scoped>
.binContainer {
  height: calc(100vh - 165px);
  background-color: #f5f7f9;
  // background-color: white;
  padding: 0;
  display: flex;
}
.btns {
  display: flex;
  justify-content: center;
  margin: 10px 0;
}
.header {
  height: 50px;
  display: flex;
  background-color: #f5f7f9;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.processTree {
  width: 220px;
  height: 100%;
  border-right: 1px solid rgba(0, 0, 0, 0.1);
  .treeChild {
    background: #f2f2f2;
    padding: 20px 8px 10px 8px;
    .childItem {
      width: 100%;
      height: 28px;
      background: #ffffff;
      border-radius: 4px 4px 4px 4px;
      border: 1px solid rgba(35, 32, 50, 0.1);
      margin-bottom: 10px;
      text-align: center;
    }
  }
}

.flowBox {
  flex: 1;
  display: flex;
  justify-content: center;
  overflow-y: auto;
  .flowItem:hover {
    .flowDelete {
      visibility: visible;
    }
  }
}

.detailInfo {
  width: 320px;
  height: 100%;
  background-color: white;
  border-left: 1px solid rgba(0, 0, 0, 0.1);
  .opBox {
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    padding: 0 20px;
    height: 150px;
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    align-items: center;
  }
  .editProcces {
    display: flex;
    justify-content: center;
    margin-bottom: 15px;
  }
}

.title {
  line-height: 44px;
  color: #6f7991;
  font-size: 14px;
  font-weight: bold;
  text-align: left;
  margin-left: 20px;
}
.title2 {
  color: #232032;
  font-size: 14px;
  text-align: left;
  margin-left: 19px;
}
.tipContent {
  width: 100%;
  text-align: center;
  margin-top: 20px;
  color: #e6a23c;
}
</style>

<style>
.el-collapse-item__content {
  padding: 0;
}
</style>
