<script setup lang="ts">
import { useCompRef } from "@/utils/useCompRef";
import { ElIcon, ElInput, ElMessageBox, ElTree } from "element-plus";
import { h, ref } from "vue";
import { Document, Folder, Lock, Open, Sort } from "@element-plus/icons-vue";
import { stringIsBlank } from "@/utils/blank-utils";
import { xcMessage } from "@/utils/xiaochan-element-plus";
import {
  emrMitt,
  isCourse,
  patientInfo,
} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
import {
  delDir,
  electronicMedicalRecordSequencing,
  newDir,
  rename,
} from "@/api/zhu-yuan-yi-sheng/emr-patient";
import { useDialog } from "@/components/cy/CyDialog/index";
import AddEmrDialog from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/add-emr-dialog/AddEmrDialog.vue";
import { emrRootContextKey } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore";
import ContextMenu from "@imengyu/vue3-context-menu";

const props = defineProps<{
  treeData: any[];
}>();

const root = inject(emrRootContextKey);

const emits = defineEmits(["nodeClick", "refresh"]);

const inputValue = ref("");
const treeRef = useCompRef(ElTree);

const defaultProps = {
  children: "children",
  label: "name",
};

const handleNodeClick = (data, node) => {
  if (data.type === "group-category") return;
  if (data.courseJumpId) {
    emits("nodeClick", {
      ...node.parent.data,
      courseJumpId: data.courseJumpId,
    });
  } else {
    emits("nodeClick", data);
  }
};

function inputChange() {
  treeRef.value?.filter(inputValue.value);
}

const filterNode = (query: string, node) => {
  if (!query) return true;
  return node.name.includes(query);
};

let drag = new Map();

const dragEnd = (moveNode, inNode, type, event) => {
  if (type === "none") return;
  let temp = {
    newParent: inNode.data.emrDocumentId,
    oldParent: moveNode.data.parent,
  };
  drag.set(moveNode.data.id, temp);
};

const dragLimit = (moveNode, inNode, type) => {
  if (moveNode.data.jump) return false;
  if (inNode.data.emrDocumentId && type === "inner") {
    return inNode.data.type !== "category";
  }
};

const allowDrag = node => {
  if (isCourse(node.data.emrCategoryCode)) {
    return true;
  }
  return node.data.type !== "group-category";
};

const isItAFolder = data => {
  return h(ElIcon, null, {
    default: () => {
      if (data.type === "category") {
        return h(Document);
      } else {
        return h(Folder);
      }
    },
  });
};

function isFiler(data) {
  return data.type !== "group-category";
}

const getDirName = async (title: string): Promise<string> => {
  return ElMessageBox.prompt("文件夹名称", title, {
    type: "info",
    inputErrorMessage: "名称不能为空",
    inputPattern: /\S/,
  }).then(({ value }) => {
    return value;
  });
};

const contextmenuItemV2 = (e, data) => {
  e.preventDefault();
  e.stopPropagation();

  function createVerification() {
    if (isCourse(data.code)) {
      return false;
    }
    return !isFiler(data);
  }

  const disabledChangeDir = data.data.parent === null;

  ContextMenu.showContextMenu({
    x: e.x,
    y: e.y,
    items: [
      {
        disabled: !createVerification(),
        label: "新建文件夹",
        onClick: async () => {
          const name = await getDirName("新建文件夹");
          await newDir({
            parent: data.folderId,
            patNo: patientInfo.value.inpatientNo,
            times: patientInfo.value.admissTimes,
            name: name,
          });
          emits("refresh");
        },
      },
      {
        disabled: !createVerification(),
        label: "新建病历",
        onClick: () => {
          useDialog<any>(AddEmrDialog, {
            dialogProps: {
              title: `在【${data.name}】文件夹下面创建病历`,
              top: "2%",
            },
            showConfirm: false,
            params: {
              templateData: root.store.emrTemplate.value.emrTree,
              deptTree: root.store.emrTemplate.value.deptTree,
            },
          }).then(res => {
            // @ts-ignore
            emrMitt.emit("loadTemplate", { ...res, parent: data.folderId });
          });
        },
      },
      {
        label: "打开（只读）",
        onClick: () => {
          if (!data.id) {
            xcMessage.error("请选中保存的病历。");
            return;
          }
          emrMitt.emit("只读病历", data.id);
        },
        icon: h(ElIcon, {}, () => h(Open)),
        disabled: !isFiler(data),
      },
      {
        label: "确认排序",
        onClick: () => {
          let temp = [];
          drag.forEach((value, key) => {
            if (value.newParent !== value.oldParent) {
              temp.push({ id: key, parent: value.newParent });
            }
          });
          if (temp.length === 0) {
            drag.clear();
            return xcMessage.error("文件夹没有变化，无需点击。");
          }
          electronicMedicalRecordSequencing(temp).then(() => {
            drag.clear();
          });
        },
        disabled: drag.size === 0,
        icon: h(ElIcon, {}, () => h(Sort)),
      },
      {
        label: "修改文件夹名称",
        onClick: async () => {
          const name = await getDirName("重命名");
          await rename(name, data.id);
          emits("refresh");
        },
        disabled: disabledChangeDir,
      },
      {
        label: "删除文件夹",
        onClick: async () => {
          await ElMessageBox.confirm(
            "是否删除该文件夹，里面的病历并不会删除",
            "删除",
            { type: "error" }
          );
          await delDir(data.id);
          emits("refresh");
        },
        disabled: disabledChangeDir,
      },
    ],
  });
};

const contextmenuItem = (event, data) => {
  let tempData = {
    id: data.emrDocumentId,
    code: data.emrCategoryCode,
    patNo: data.patNo,
    times: data.times,
    name: data.name ? data.name : data.emrName,
    parent: data.parent,
    type: data.type,
    folderId: data.emrDocumentId,
    data: data,
  };
  contextmenuItemV2(event, tempData);
};

const nullToEmpty = val => {
  return stringIsBlank(val) ? "" : " \\ " + val;
};

const fileName = val => {
  return val.name + nullToEmpty(val.createName) + nullToEmpty(val.createDate);
};
</script>

<template>
  <div class="layout_container">
    <div>
      <el-input
        ref="inputRef"
        v-model="inputValue"
        @input="inputChange"
        clearable
      />
    </div>
    <div>
      <el-tree
        class="down-tree"
        :data="props.treeData"
        :props="defaultProps"
        @node-click="handleNodeClick"
        node-key="emrDocumentId"
        ref="treeRef"
        draggable
        @node-drag-end="dragEnd"
        :allow-drag="allowDrag"
        :allow-drop="dragLimit"
        @node-contextmenu="contextmenuItem"
        highlight-current
        :filter-node-method="filterNode"
        default-expand-all
      >
        <template #default="{ node, data }">
          <el-icon v-if="data.submit">
            <Lock />
          </el-icon>
          <component :is="isItAFolder(data)" />
          <span :title="fileName(data)">{{ fileName(data) }}</span>
        </template>
      </el-tree>
    </div>
  </div>
</template>
