<template>
  <div>
    <Breadcrumb :items="['系统管理', '部门管理']" :title="'部门管理'">
    </Breadcrumb>
    <div class="container">
      <a-row :gutter="20" align="stretch">
        <a-col :span="24">
          <a-card class="general-card" style="min-height: 80vh">
            <template #title>
              <a-row>
                <a-col :flex="1">
                  <a-form
                    :model="filterForm"
                    :label-col-props="{ span: 6 }"
                    :wrapper-col-props="{ span: 18 }"
                    label-align="left"
                    auto-label-width
                  >
                    <a-row :gutter="16">
                      <a-col :span="5">
                        <a-form-item field="keyword" label="模糊匹配" hide-label
                          ><a-input-search
                            v-model="filterForm.keyword"
                            placeholder="根据部门名称模糊匹配"
                            allow-clear
                            @search="filterGroup()"
                            @clear="filterGroup()"
                            @keyup.enter="filterGroup()"
                          />
                        </a-form-item>
                      </a-col>
                    </a-row>
                  </a-form>
                </a-col>
              </a-row>
            </template>
            <a-divider style="margin-top: 0" />
            <a-table
              ref="groupTableRef"
              :pagination="false"
              :columns="tableColumns"
              :data="orgTree"
              :hide-expand-button-on-empty="true"
              :bordered="{ cell: true }"
              :hoverable="true"
              table-layout-fixed
            >
              <template #name="{ record }">
                <a-row
                  justify="space-between"
                  @mouseenter="toggleSmallBtn(record)"
                  @mouseleave="leaveRow(record)"
                >
                  <a-col :span="20">
                    {{ record.name }}
                  </a-col>
                  <a-col v-show="record.showMore" :span="1">
                    <a-space
                      ><icon-plus
                        v-permission="[Base.CFG_ORG_ADD]"
                        :size="16"
                        style="cursor: pointer"
                        @click="showGroupModal(0, record)"
                      />
                      <a-dropdown
                        trigger="click"
                        popup-container="body"
                        @popup-visible-change="changeDropMenu($event, record)"
                      >
                        <icon-more
                          v-permission="[
                            Base.CFG_ORG_MODIFY,
                            Base.CFG_ORG_REMOVE
                          ]"
                          :size="16"
                          style="transform: rotate(90deg); cursor: pointer"
                          @click="showDropdwon = true"
                        />
                        <template #content>
                          <a-doption
                            v-permission="[Base.CFG_ORG_MODIFY]"
                            @click="showGroupModal(1, record)"
                          >
                            <template #icon>
                              <icon-edit style="color: rgb(var(--success-6))" />
                            </template>
                            <template #default>修改</template>
                          </a-doption>
                          <a-doption
                            v-permission="[Base.CFG_ORG_REMOVE]"
                            @click="handleRemoveGroup(record)"
                          >
                            <template #icon>
                              <icon-minus-circle
                                style="color: rgb(var(--danger-6))"
                              />
                            </template>
                            <template #default>删除</template>
                          </a-doption>
                        </template>
                      </a-dropdown>
                    </a-space>
                  </a-col>
                </a-row>
              </template>
            </a-table>
          </a-card>
        </a-col>
      </a-row>
    </div>
    <vModal
      v-model:visible="visibleGroupModal"
      :title="modalTitle"
      @modal-handle-ok="groupHandleOk"
      @modal-handle-cancel="groupHandleCancel"
    >
      <div style="padding: 10px 15px">
        <a-form
          ref="groupFormRef"
          :model="groupForm"
          :auto-label-width="true"
          label-align="right"
          :rules="groupFormRules"
        >
          <a-form-item field="name" label="名称" show-colon>
            <a-input v-model="groupForm.name" placeholder="请输入部门名称" />
          </a-form-item>
          <a-form-item field="memo" label="备注" show-colon>
            <a-textarea
              v-model="groupForm.memo"
              placeholder="请输入部门备注"
              allow-clear
              :show-word-limit="true"
              :max-length="256"
              :auto-size="{
                minRows: 5
              }"
            />
          </a-form-item>
        </a-form>
      </div>
    </vModal>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick, onMounted, h } from 'vue'
import { FormInstance } from '@arco-design/web-vue/es/form'
import { TableInstance } from '@arco-design/web-vue/es/table'
import { Modal, Message } from '@arco-design/web-vue'
import { removeNode, appendNode, modifyNode } from '@/utils'
import vModal from '@/components/modal/index.vue'
import { useEmitt } from '@/logics/mitt/useEmitt'
import { Base } from '@/enums/api'
import { addOrg, getOrgTree, modifyOrg, removeOrg } from '@/api/base/org'
import { DomainTree } from '@/types/domain'
// import { GroupTree, AddGroupResParams } from '@/types/device'

const { emitter } = useEmitt()
const groupFormRef = ref<FormInstance>()
const groupTableRef = ref<TableInstance>()

const visibleGroupModal = ref(false) // 是否显示group对话框
const showDropdwon = ref(false) // 是否显示group对话框
const modalType = ref(0) // 对话框类型，0：添加，1：修改
const modalTitle = ref('') // 对话框标题
const orgTree = ref<DomainTree[]>([]) // 部门树

/**
 * 条件筛选表单
 */
const filterForm = reactive<{
  keyword?: string
}>({
  keyword: undefined
})

/**
 * 部门表单
 */
const groupForm = reactive<{
  id?: number
  name: string
  memo?: string
}>({
  id: undefined,
  name: '',
  memo: ''
})

/**
 * 部门表单验证规则
 */
const groupFormRules = {
  name: [
    { required: true, message: '名称不能未空', trigger: 'blur' },
    {
      minLength: 2,
      maxLength: 20,
      message: '名称长度大于2个字节，且小于20个字节',
      validateTrigger: ['blur', 'change']
    }
  ]
}

/**
 * 部门列表头部标题
 */
const tableColumns = [
  {
    title: '名称',
    dataIndex: 'name',
    slotName: 'name'
  },
  {
    title: '备注',
    dataIndex: 'memo'
  }
]

/**
 * 根据表单按条件筛选角色列表
 */
const filterGroup = (): void => {
  getTree().then(() => console.log('获取部门树'))
}

/**
 * 递归获取ng-tree需要的结构体
 * @param group 接口返回的树状数组
 */
const getNodesTree = (group: DomainTree): DomainTree => {
  group.key = group.id.toString()
  group.title = group.name
  group.showMore = false
  if (group.children && group.children.length > 0) {
    group.children.map(res => getNodesTree(res))
  }
  return group
}

/**
 * 鼠标放上
 * @param group
 */
const toggleSmallBtn = (group: DomainTree) => {
  group.showMore = true
}

/**
 * 鼠标离开时，如果dropmen未显示时隐藏more操作组
 */
const leaveRow = (group: DomainTree) => {
  if (showDropdwon.value) {
    return
  }
  group.showMore = false
}

/**
 * dropmenu隐藏事件
 * @param visible
 * @param group
 */
const changeDropMenu = (visible: boolean, group: DomainTree) => {
  showDropdwon.value = visible
  group.showMore = visible
}

/**
 * 获取用户列表
 */
const getTree = async () => {
  const { tree } = await getOrgTree()
  orgTree.value = tree.map(org => {
    return getNodesTree(org)
  })
}

/**
 * 隐藏group对话框，重置表单
 */
const groupHandleCancel = () => {
  groupFormRef.value!.resetFields() // 初始化表单值
}

/**
 * 显示部门modal
 * @param type modal 类型
 * @param group
 */
const showGroupModal = (type: number, group: DomainTree) => {
  const isAdd = type === 0
  const { memo, name, id } = group!
  modalType.value = type
  if (isAdd) {
    modalTitle.value = `在 ${group.name} 下添加部门`
    visibleGroupModal.value = true
    nextTick(() => {
      groupForm.id = group.id
    })
  } else {
    modalTitle.value = `修改 ${group.name} 信息`
    visibleGroupModal.value = true
    nextTick(() => {
      groupForm.id = id
      groupForm.name = name
      groupForm.memo = memo
    })
  }
}

/**
 * 点击确认按钮时，cb(false)时不会继续后续操作
 * @param cb 回调函数，
 */
const groupHandleOk = async (cb: (closed: boolean) => void) => {
  const isValid = await groupFormRef.value?.validate()
  if (isValid) {
    return cb(false)
  }
  const isAdd = modalType.value === 0
  const { id, name, memo } = groupForm
  if (isAdd) {
    const res = await addOrg(name, id, memo)
    const node: DomainTree = {
      id: res.id,
      key: res.id.toString(),
      name,
      title: name,
      memo,
      children: []
    }
    appendNode(orgTree.value, id!, node)
    Message.success('添加成功')
  } else {
    await modifyOrg(id!, name, memo)
    const node: DomainTree = {
      id: id!,
      key: id!.toString(),
      name,
      title: name,
      memo,
      children: []
    }
    modifyNode(orgTree.value, id!, node)
    Message.success('修改成功')
  }
  emitter.emit('get_group_tree')
  return cb(true)
}

/**
 * 删除部门
 * @param group
 */
const handleRemoveGroup = async (group: DomainTree) => {
  const { id, name } = group
  const title = {
    setup() {
      return () => h('strong', '警告')
    }
  }
  const ModalContent = {
    setup() {
      return () =>
        h('span', { style: 'margin-left: 10px;' }, [
          h('span', `确认删除 `),
          h('strong', `${name}`),
          h('span', ` 部门吗？`)
        ])
    }
  }
  Modal.warning({
    title: () => h(title),
    content: () => h(ModalContent),
    alignCenter: true,
    titleAlign: 'start',
    draggable: true,
    escToClose: true,
    width: 300,
    simple: true,
    hideCancel: false,
    onOk: async () => {
      await removeOrg(id)
      orgTree.value = removeNode(orgTree.value, id)
      Message.success('删除成功')
      emitter.emit('get_group_tree')
    }
  })
}

onMounted(async () => {
  try {
    await getTree().then(() => console.log('获取部门树'))
    groupTableRef.value?.expandAll(true)
  } catch (e) {
    console.log(e)
  }
})
</script>

<script lang="ts">
export default {
  name: 'Organization'
}
</script>

<style scoped lang="less">
.container {
  padding: 20px 20px 20px 20px;
  .general-card {
    :deep(.arco-card-header) {
      padding: 20px 20px 0 20px;
    }
  }
}
</style>
