<script setup lang="tsx">
import { reactive, ref, unref, nextTick, watch } from 'vue'
import {
  getSysOrganListApi,
  saveSysOrganApi,
  delSysOrganListApi,
  delSysOrganApi,
  getSysOrgType
} from '@/api/param/SysOrgan'
import { TableData, TreeNode, ListItem } from '@/api/param/SysOrgan/types'
import { useTable } from '@/hooks/web/useTable'
import { useI18n } from '@/hooks/web/useI18n'
import { Table, TableColumn } from '@/components/Table'
import { Search } from '@/components/Search'
import { FormSchema } from '@/components/Form'
import { ContentWrap } from '@/components/ContentWrap'
import Write from './components/Write.vue'
import Detail from './components/Detail.vue'
import Organ from './components/Organ.vue'
import { Dialog } from '@/components/Dialog'
import { useRoute } from 'vue-router'
import { useTagsView } from '@/hooks/web/useTagsView'
import { ElButton, ElTree, ElPopconfirm, ElLink, ElMessage } from 'element-plus'
import { getOrgTreeByTreeId } from '@/api/common'
import { transfDictList, findListLabel } from '@/utils'

import type Node from 'element-plus/es/components/tree/src/model/node'
import type { DragEvents } from 'element-plus/es/components/tree/src/model/useDragNode'
import type { NodeDropType } from 'element-plus/es/components/tree/src/tree.type'

const { setTitle } = useTagsView()

const { params } = useRoute()

const val = ref(params.id as string)

setTitle(`机构树管理-${val.value}`)

const { t } = useI18n()

const ids = ref<string[]>([])

/** 机构类型 */
const ORGAN_TYPE_LIST = ref<ListItem[]>([])

const { tableRegister, tableState, tableMethods } = useTable({
  fetchInitParamsApi: async () => {
    const res = await getSysOrgType()
    if (res) {
      ORGAN_TYPE_LIST.value = transfDictList(res.body.result)
    }
  },
  fetchDataApi: async () => {
    const { currentPage, pageSize } = tableState
    const res = await getSysOrganListApi({
      pageNum: unref(currentPage),
      pageSize: unref(pageSize),
      ...unref(searchParams),
      treeId: val.value
    })
    return {
      list: res.body.list,
      total: res.body.total
    }
  },
  fetchDelApi: async () => {
    const res = await delSysOrganListApi(unref(ids))
    return !!res
  }
})

const { loading, dataList, total, currentPage, pageSize } = tableState
const { getList, refresh } = tableMethods

const tableColumns = reactive<TableColumn[]>([
  {
    field: 'selection',
    type: 'selection'
  },
  {
    field: 'code',
    label: '机构号'
  },
  {
    field: 'orgname',
    label: '机构名称'
  },
  {
    field: 'address',
    label: '归属区域'
  },
  {
    field: 'orgLeveType',
    label: '类型',
    formatter: (row: Recordable, __: TableColumn) => {
      const label = findListLabel(unref(ORGAN_TYPE_LIST), row.orgLeveType)
      if (label) {
        return label
      }
    },
    hidden:true
  }
])

const searchSchema = reactive<FormSchema[]>([
  {
    field: 'orgname',
    label: '机构名称',
    component: 'Input'
  },
  {
    field: 'code',
    label: '机构号',
    component: 'Input'
  },
  {
    field: 'address',
    label: '归属区域',
    component: 'Input',
  }
])

const searchParams = ref({})
const setSearchParams = (data: any) => {
  searchParams.value = data
  getList()
}

const dialogVisible = ref(false)
const dialogTitle = ref('')

const currentRow = ref()
const actionType = ref('')

const writeRef = ref<ComponentRef<typeof Write>>()

const saveLoading = ref(false)

/** 保存 **/
const save = async () => {
  const write = unref(writeRef)
  const formData = await write?.submit()
  if (formData) {
    saveLoading.value = true
    const res = await saveSysOrganApi(formData)
      .catch(() => {})
      .finally(() => {
        saveLoading.value = false
      })
    if (res) {
      dialogVisible.value = false
      currentPage.value = 1
      getList()
    }
  }
}

const disabled = ref(true)

const onSelectionChange = (selection: TableData[]) => {
  disabled.value = selection.length === 0
}

/** 机构树 **/
const treeEl = ref<typeof ElTree>()

const treeExpandKeys = ref<string[]>(['0'])
const currentNodeKey = ref('')
const orgTreeList = ref<TreeNode[]>([])
const fetchOrgTree = async () => {
  const res = await getOrgTreeByTreeId(val.value)
  if (res) {
    orgTreeList.value = res.body.result
    if (res.body.result[0] && res.body.result[0]?.children && res.body.result[0].id) {
      treeExpandKeys.value = [res.body.result[0].id]
    }
  }
}
fetchOrgTree()

/** 节点参数 **/
const defaultProps = {
  children: 'childs',
  label: 'nodeName'
}

/** 拖拽事件 **/
const handleDragEnd = (
  draggingNode: Node,
  dropNode: Node,
  dropType: NodeDropType,
  ev: DragEvents
) => {
  console.log('tree drag end:', dropNode && dropNode.label, dropType, draggingNode, ev)
}

/** 展示机构 */
const openOrgan = async (data: TreeNode) => {
  organVisible.value = true
  currentNodeKey.value = data.id
}

/** 保存节点 */
const addTreeNode = async () => {
  const organ = unref(organRef)
  const tableData = await organ?.submit()
  const organList = tableData.map((item) => item.id)
  const data = {
    parentId: currentNodeKey.value,
    organList: organList
  }
  console.log(data)
}

/** 删除节点 */
const delNode = async (node: Node, data: TreeNode) => {
  // 数据删除
  const res = await delSysOrganApi(data.id)
  if (res) {
    const { code, errMsg } = res.head
    if (code === '0') {
      ElMessage.success('删除成功!')
      // 节点删除
      const parent = node.parent
      const children: TreeNode[] = parent.data.childs || parent.data
      const index = children.findIndex((d) => d.id === data.id)
      children.splice(index, 1)
      orgTreeList.value = [...orgTreeList.value]
    } else {
      ElMessage.error(errMsg || '删除失败!')
    }
  }
}

const organVisible = ref(false)
const organRef = ref<ComponentRef<typeof Organ>>()
</script>

<template>
  <ContentWrap>
    <div class="flex w-100% h-100%">
      <div class="w-600px flex-shrink-0">
        <ElTree
          ref="treeEl"
          :data="orgTreeList"
          :expand-on-click-node="false"
          node-key="id"
          :current-node-key="currentNodeKey"
          :props="defaultProps"
          :default-expanded-keys="treeExpandKeys"
          draggable
          @node-drag-end="handleDragEnd"
        >
          <template #default="{ node, data }">
            <span class="r-tree-title">
              <span class="r-plain-tree-title">{{ node.label }}</span>
              <span>
                <ElLink :underline="false" @click="() => openOrgan(data)">
                  <Icon icon="ep:circle-plus" :size="14" />
                </ElLink>
                <ElPopconfirm
                  @confirm="() => delNode(node, data)"
                  :title="t('common.delTableMsg')"
                  :width="200"
                >
                  <template #reference>
                    <ElLink :underline="false">
                      <Icon icon="ep:remove" :size="14" />
                    </ElLink>
                  </template>
                </ElPopconfirm>
              </span>
            </span>
          </template>
        </ElTree>
      </div>
      <div class="flex-1 ml-10px">
        <Search :schema="searchSchema" @reset="setSearchParams" @search="setSearchParams" />

        <Table
          :columns="tableColumns"
          v-model:pageSize="pageSize"
          v-model:currentPage="currentPage"
          default-expand-all
          node-key="id"
          :data="dataList"
          :loading="loading"
          :pagination="{
            total
          }"
          @selection-change="onSelectionChange"
          @register="tableRegister"
          @refresh="refresh"
        />
      </div>
    </div>
  </ContentWrap>

  <Dialog v-model="dialogVisible" :title="dialogTitle">
    <Write
      v-if="actionType !== 'detail'"
      ref="writeRef"
      :current-row="currentRow"
      :action-type="actionType"
    />
    <Detail v-if="actionType === 'detail'" :current-row="currentRow" />
    <template #footer>
      <ElButton v-if="actionType !== 'detail'" type="primary" :loading="saveLoading" @click="save">
        {{ t('dialogDemo.save') }}
      </ElButton>
      <ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
    </template>
  </Dialog>

  <Dialog v-model="organVisible" title="选择挂载的机构" width="1200px" max-height="560px">
    <Organ ref="organRef" />
    <template #footer>
      <ElButton type="primary" :loading="saveLoading" @click="addTreeNode">
        {{ t('dialogDemo.save') }}
      </ElButton>
      <ElButton @click="organVisible = false">{{ t('dialogDemo.close') }}</ElButton>
    </template>
  </Dialog>
</template>

<style lang="less" scoped>
.el-tree-node {
  .el-link {
    opacity: 0;
    margin-left: 4px;
  }
}

.el-tree-node__content:hover .el-link {
  opacity: 1;
}
</style>
