<template>
  <div>
    <el-input v-model="filterText"
              placeholder="节点过滤"
              style="width: 100%"
              @input="filterChange" clearable/>
    <el-radio-group v-model="templateType" @change="typeChange">
      <el-radio-button v-if="props.isCreate" :disabled="!editor" :label="0">全院</el-radio-button>
      <el-radio-button v-if="props.isCreate" :disabled="!editor" :label="1">科室</el-radio-button>
      <el-radio-button :label="2">当前</el-radio-button>
      <el-radio-button :label="3">历史</el-radio-button>
    </el-radio-group>
    <div :style="{maxHeight : maxHeight - 100 + 'px'}"
         style="overflow: auto; "
         class="down-tree">
      <el-tree v-show="templateType === 3"
               :props="defaultProps"
               ref="hisTreeRef"
               :filter-node-method="filterNode"
               :data="hisData"
               @node-click="hisClick">
      </el-tree>
      <el-tree v-show="templateType !== 3"
               :data="treeData"
               :props="defaultProps"
               @node-click="handleNodeClick"
               node-key="_id"
               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>
    <right-click-menu :mouse-position="mousePosition" :config="opt"/>
  </div>
</template>

<script setup lang="ts">
import {
  electronicMedicalRecordSequencing,
  getEmrTree, getPastHistory,
  getPatientDataTree,
  queryWhetherThePatientHasASpecifiedMedicalRecord,
  whetherItExistsInTheDepartment
} from "@/api/zhu-yuan-yi-sheng/emr-patient";
import {BizException, ExceptionEnum} from "@/utils/BizException";
import {
  canIUnlockIt,
  emrConfig,
  emrMitt,
  unlockEnum
} from '@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init'
import {stringIsBlank} from "@/utils/blank-utils";
import {getAllWards} from "@/api/zhu-yuan-yi-sheng/resident-doctor";
import RightClickMenu from "@/components/menu-item/RightClickMenu.vue";
import {xcMessage} from "@/utils/xiaochan-element-plus";
import {ElIcon, ElTree} from "element-plus";
// @ts-ignore
import {Folder, Document, Open, Sort, View} from "@element-plus/icons-vue";
import {isDev} from "@/utils/public";
import {ref, computed, h, onMounted} from 'vue'
import {useCompRef} from "@/utils/useCompRef";
import {userInfoStore} from "@/utils/store-public";

const props = defineProps({
  maxHeight: {
    type: Number
  },
  huanZheXinXi: {
    type: Object
  },
  patientData: {
    type: Object
  },
  extractData: {
    type: Object
  },
  doctorGrade: {
    type: Number
  },
  isCreate: {
    type: Boolean,
    default: true
  }
})

let editor = emrConfig.value.editor

const emit = defineEmits(['nodeClick', 'typeChange', 'patientMedicalRecord', 'openAndSaveTheMedicalRecord'])

const returnData = ref({
  emrTree: [],
  deptTree: [],
  patientTree: []
})
const filterText = ref('')
const treeRef = useCompRef(ElTree)
const dialog = ref(false)

let wardList = []

const defaultProps = {
  children: 'children',
  label: 'name',
}

const templateType = ref(0)

const treeData = computed(() => {
  switch (templateType.value) {
    case 0 :
      return returnData.value.emrTree;
    case 1:
      return returnData.value.deptTree;
    case 2:
      return returnData.value.patientTree;
  }
})

const wardCreationJudgment = async () => {
  if (determineWhetherItCanBeCreated()) {
    return
  }
  if (await judgeTheCreationOfTransfer()) {
    return;
  }
  if (canIUnlockIt(unlockEnum.转科创建病历)) {
    return;
  }
  if (isDev) {
    return
  }
  BizException(ExceptionEnum.MESSAGE_ERROR, "当前患者所在病区不在您的管理病区范围内，无法创建病历。");
}

const handleNodeClick = async (val, node, parent, event) => {
  if (val.type === 'group-category') return
  let temp: {
    code?: string
    value?: string
    // 电子病历的 id 如果是新建就没有
    documentId?: string | null
    categoryId?: string | null
    // 电子病历的 编码
    categoryCode?: string
    // 患者的 id
    patientId?: string | null
    // 电子病历 名称
    name?: string
    // 创建人 id
    createId?: string | null
    // 父级节点
    parent?: string
    createName?: string
  } = {}
  if (templateType.value === 0 || templateType.value === 1) {
    temp = {
      documentId: null,
      categoryCode: val.code,
      categoryId: val._id,
      patientId: null,
      name: val.name,
      createId: null,
      parent: val.parent,
    }
    await wardCreationJudgment()
  } else if (templateType.value === 2) {
    temp = {
      documentId: val.emrDocumentId,
      categoryCode: val.emrCategoryCode,
      categoryId: null,
      patientId: null,
      name: val.name ? val.name : val.emrName,
      createId: val.createId,
      createName: val.createName
    }
    if (val.jump) {
      let tempVal = node.parent.data
      emrMitt.emit('audit', {
        id: tempVal.id,
        code: tempVal.emrCategoryCode,
        createId: tempVal.createId,
        referPhysician: props.huanZheXinXi.referPhysician,
        patNo: props.huanZheXinXi.inpatientNo,
        times: props.huanZheXinXi.admissTimes
      });
    } else {
      emrMitt.emit('audit', {
        id: val.id,
        code: val.emrCategoryCode,
        createId: val.createId,
        referPhysician: props.huanZheXinXi.referPhysician,
        patNo: props.huanZheXinXi.inpatientNo,
        times: props.huanZheXinXi.admissTimes
      });
    }
  }
  if (val.children) {
    return
  }

  if (val.labels) {
    // 根据 这个编码来限制是不是唯一一个
    if (val.labels.includes('唯一') && templateType.value !== 2) {
      let flag = await queryWhetherThePatientHasASpecifiedMedicalRecord({
        patNo: props.huanZheXinXi.inpatientNo,
        times: props.huanZheXinXi.admissTimes,
        emrCategoryCode: val.code
      })
      if (flag) {
        BizException(ExceptionEnum.LOGICAL_ERROR, '此病历只能创建一次。')
      }
    }
  }

  if (val.jump) {
    temp.code = val.code
    temp.value = val.value
    emit('nodeClick', temp, true, templateType.value);
  } else {
    emit('nodeClick', temp, false, templateType.value);
  }
}

const determineWhetherItCanBeCreated = () => {
  if (userInfoStore.value.code === props.patientData['管床医生编码'] || props.doctorGrade > 1) {
    return true;
  }
  return wardList.includes(props.huanZheXinXi.ward);
}

const judgeTheCreationOfTransfer = async () => {
  let res = await whetherItExistsInTheDepartment(props.huanZheXinXi.inpatientNo, props.huanZheXinXi.admissTimes) as any;
  if (res === null) {
    return false;
  }
  if (res.timeout) {
    return false;
  }
  return wardList.includes(res.fDeptCode);
}

const typeChange = (val) => {
  emit("typeChange", val)
}

const filterChange = (val) => {
  try {
    hisTreeRef.value.filter(val)
  } catch {

  }
  try {
    treeRef.value.filter(val);
  } catch {

  }
}

const filterNode = (value, data) => {
  if (!value) return true
  return data.name.includes(value)
}

const changeTemplateType = (val) => {
  templateType.value = val
  typeChange(val)
}

const deleteTheSpecifiedNode = (id) => {
  for (let i = 0, len = returnData.value.patientTree.length; i < len; i++) {
    let item = returnData.value.patientTree[i]
    if (item.emrDocumentId === id) {
      returnData.value.patientTree.splice(i, 1)
      return
    }
    if (item.children) {
      for (let j = 0; j < item.children.length; j++) {
        let child = item.children[j]
        if (child.emrDocumentId === id) {
          item.children.splice(i, 1)
          return
        }
      }
    }
  }
}

let findNode = false
const diseaseDurationRecordTime = (id, list) => {
  findNode = false;
  findMedicalRecordById(id, list, returnData.value.patientTree);
}

const findMedicalRecordById = (id, roundTimes, list) => {
  for (let i = 0, len = list.length; i < len; i++) {
    if (findNode) return;
    let item = list[i]
    if (item.emrDocumentId === id) {
      findNode = true
      item.type = 'group-category'
      item.children = roundTimes
      return
    }

    if (item.children) {
      findMedicalRecordById(id, roundTimes, item.children)
    }

  }
}

const queryData = () => {
  getPatientDataTree(props.huanZheXinXi.inpatientNo, props.huanZheXinXi.admissTimes).then((res) => {
    if (res?.length > 0) {
      templateType.value = 2
      emit('patientMedicalRecord')
    }
    returnData.value.patientTree = res
  })
}

const hisData = ref([])
const hisTreeRef = ref(null)
const pastHistory = () => {
  getPastHistory(props.huanZheXinXi.inpatientNo, props.huanZheXinXi.admissTimes).then((res) => {
    let temp = []
    for (let key in res) {
      temp.push({
        name: `第${key}次住院`,
        children: res[key]
      })
    }
    hisData.value = temp
  })
}

const hisClick = (val) => {
  if (!val.emrDocumentId) return
  emrMitt.emit('setShowIframe', 3, val.emrDocumentId)
}

const fileName = (val) => {
  if (val.jump) {
    let tempDate = val.trueCreationTime
    if (!tempDate) {
      tempDate = val.createDate
    }
    return val.name + nullToEmpty(val.createName) + nullToEmpty(tempDate)
  }
  if (templateType.value === 2) {
    return val.name + nullToEmpty(val.createName) + nullToEmpty(val.createDate)
  } else {
    return val.name
  }
}

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

const mousePosition = ref()
const opt = [
  {
    name: '打开（只读）', click: (data) => {
      if (!data.unlock.id) {
        xcMessage.error('请选中保存的病历。')
        return
      }
      emit('openAndSaveTheMedicalRecord', data.unlock.id)
    },
    icon: h(ElIcon, {}, () => h(Open))
  },
  {
    name: '同时打开', click: (data) => {
      if (!data.unlock.id) {
        xcMessage.error('请选中保存的病历。')
        return
      }
      emit('openAndSaveTheMedicalRecord', data.unlock.id, 3)
    },
    icon: h(ElIcon, {}, () => h(View))
  },
  {
    name: '确认排序', click: (data) => {
      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()
      })
    },
    validator: () => {
      return drag.size > 0
    },
    icon: h(ElIcon, {}, () => h(Sort))
  }
]
const contextmenuItem = (event, data) => {
  let tempData;
  if (data.emrDocumentId) {
    tempData = {
      id: data.emrDocumentId,
      code: data.emrCategoryCode,
      patNo: data.patNo,
      times: data.times,
      name: data.name ? data.name : data.emrName,
    }
  } else {
    tempData = {
      id: null,
      code: data.code,
      patNo: props.huanZheXinXi.inpatientNo,
      times: props.huanZheXinXi.admissTimes,
      name: data.name,
    }
  }
  event.returnValue = false;
  mousePosition.value = {
    event,
    index: 0,
    data: {
      unlock: tempData,
      original: data
    }
  };
}

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

const dragLimit = (moveNode, inNode, type) => {
  if (templateType.value !== 2) return false;
  if (moveNode.data.jump) return false;
  if (inNode.data._id && type === 'inner') {
    return true;
  }
}

const allowDrag = (node) => {
  if (templateType.value !== 2) return false;
  if (node.data.emrCategoryCode === 'shoucibingchengjilu') {
    return true;
  }
  return node.data.type !== "group-category";
}

let drag = new Map();

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

onMounted(() => {

  emrMitt.on('患者病区判断', () => {
    return determineWhetherItCanBeCreated()
  })

  emrMitt.on('querySidebar', queryData)

  pastHistory()
  queryData()
  if (editor) {
    getAllWards().then((res) => {
      if (res.length > 0) {
        for (let i = 0, len = res.length; i < len; i++) {
          wardList.push(res[i].code)
        }
      }
    })
    getEmrTree().then((res) => {
      returnData.value.emrTree = res.all
      returnData.value.deptTree = res.dept
    })
  } else {
    templateType.value = 2
  }

})

defineExpose({
  changeTemplateType,
  deleteTheSpecifiedNode,
  diseaseDurationRecordTime,
  queryData
})


</script>

<style scoped lang="scss">
.down-tree {
  :deep(.el-tree-node.is-expanded > .el-tree-node__children) {
    display: inline;
  }
}
</style>
