<script setup lang="ts">
import { createDept, deleteDept, getDeptMembers, getDeptTree, updateDept, type Dept, type DeptDTO } from '@/api/dept'
import { getRoles } from '@/api/role'
import { Pagination, StatusTag, TableActions } from '@/components'
import type { Role } from '@/types'
import { DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined, TeamOutlined } from '@ant-design/icons-vue'
import { Button, Col, Descriptions, Drawer, Empty, Form, Input, InputNumber, Modal, Row, Select, Space, Spin, Table, Tag, Tree, TreeSelect, message } from 'ant-design-vue'
import type { ColumnsType } from 'ant-design-vue/es/table'
import { computed, onMounted, reactive, ref } from 'vue'

// 表格列定义
const columns: ColumnsType = [
  { title: '姓名', dataIndex: 'realName', key: 'realName', width: 120 },
  { title: '用户名', dataIndex: 'username', key: 'username', width: 120 },
  { title: '角色', dataIndex: 'roleNames', key: 'roleNames', ellipsis: true },
  { title: '用户类型', dataIndex: 'userType', key: 'userType', width: 100 },
  { title: '状态', dataIndex: 'status', key: 'status', width: 80 },
  { title: '操作', key: 'action', width: 100, fixed: 'right' as const }
]

// 部门类型选项
const deptTypeOptions = [
  { value: 'ADMIN', label: '行政管理' },
  { value: 'ENGINEERING', label: '工程部' },
  { value: 'SECURITY', label: '安保部' },
  { value: 'CS', label: '客服部' },
  { value: 'CLEANING', label: '保洁部' }
]

// 部门类型翻译
const getDeptTypeLabel = (type: string) => {
  const map: Record<string, string> = {
    'ADMIN': '行政管理',
    'ENGINEERING': '工程部',
    'SECURITY': '安保部',
    'CS': '客服部',
    'CLEANING': '保洁部'
  }
  return map[type] || type
}

// 部门类型颜色
const getDeptTypeColor = (type: string) => {
  const map: Record<string, string> = {
    'ADMIN': 'blue',
    'ENGINEERING': 'orange',
    'SECURITY': 'red',
    'CS': 'green',
    'CLEANING': 'cyan'
  }
  return map[type] || 'default'
}

// 树节点类型
interface TreeNode {
  key: string
  title: string
  children?: TreeNode[]
  deptData: Dept
}

// 数据状态
const treeData = ref<TreeNode[]>([])
const expandedKeys = ref<string[]>([])
const selectedKeys = ref<string[]>([])
const loading = ref(false)
const submitting = ref(false)
const drawerVisible = ref(false)
const drawerTitle = ref('')
const isEdit = ref(false)
const roles = ref<Role[]>([])
const members = ref<any[]>([])
const membersLoading = ref(false)
const currentDept = ref<Dept | null>(null)
const formRef = ref()

// 分页
const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0
})

// 分页后的数据
const paginatedData = computed(() => {
  const start = (pagination.current - 1) * pagination.pageSize
  const end = start + pagination.pageSize
  return members.value.slice(start, end)
})

// 表单
const formState = ref<DeptDTO>({
  deptName: '',
  deptCode: '',
  parentId: undefined,
  deptType: 'ADMIN',
  defaultRoleCode: '',
  sortOrder: 0
})

// 获取角色列表
const fetchRoles = async () => {
  try {
    const res = await getRoles()
    roles.value = res.data.data || []
  } catch {
    message.error('获取角色列表失败')
  }
}

// 转换为树形结构
const convertToTree = (depts: Dept[], parentId: string | null = null): TreeNode[] => {
  return depts
    .filter(d => (parentId === null && !d.parentId) || d.parentId === parentId)
    .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))
    .map(d => ({
      key: d.id!,
      title: d.deptName,
      deptData: d,
      children: convertToTree(depts, d.id!)
    }))
}

// 获取部门树
const fetchDeptTree = async () => {
  loading.value = true
  try {
    const res = await getDeptTree()
    const depts = res.data.data || []
    treeData.value = convertToTree(depts)
    // 默认展开第一级
    if (treeData.value.length > 0) {
      expandedKeys.value = treeData.value.map(n => n.key)
    }
  } catch {
    message.error('获取部门树失败')
  } finally {
    loading.value = false
  }
}

// 获取所有子部门ID
const getAllChildDeptIds = (node: TreeNode): string[] => {
  const ids = [node.key]
  if (node.children) {
    for (const child of node.children) {
      ids.push(...getAllChildDeptIds(child))
    }
  }
  return ids
}

// 根据key查找节点
const findNodeByKey = (nodes: TreeNode[], key: string): TreeNode | null => {
  for (const node of nodes) {
    if (node.key === key) return node
    if (node.children) {
      const found = findNodeByKey(node.children, key)
      if (found) return found
    }
  }
  return null
}

// 获取部门成员（含子部门）
const fetchMembers = async (deptIds: string[]) => {
  membersLoading.value = true
  const allMembers: any[] = []
  try {
    for (const deptId of deptIds) {
      const res = await getDeptMembers(deptId)
      if (res.data.data) {
        allMembers.push(...res.data.data)
      }
    }
    // 去重
    const seen = new Set()
    members.value = allMembers.filter(m => {
      if (seen.has(m.id)) return false
      seen.add(m.id)
      return true
    })
    pagination.total = members.value.length
  } catch {
    message.error('获取部门成员失败')
  } finally {
    membersLoading.value = false
  }
}

// 选择部门
const handleSelect = async (keys: any, info: any) => {
  const selectedKeysValue = keys as string[]
  if (selectedKeysValue.length > 0) {
    selectedKeys.value = selectedKeysValue
    // 从 treeData 中查找选中的节点
    const selectedNode = findNodeByKey(treeData.value, selectedKeysValue[0])
    if (selectedNode) {
      currentDept.value = selectedNode.deptData
      const deptIds = getAllChildDeptIds(selectedNode)
      await fetchMembers(deptIds)
    }
  } else {
    selectedKeys.value = []
    currentDept.value = null
    members.value = []
    pagination.total = 0
  }
}

// 分页变化
const handlePageChange = (page: number, pageSize: number) => {
  pagination.current = page
  pagination.pageSize = pageSize
}

// 新增
const handleAdd = () => {
  isEdit.value = false
  drawerTitle.value = '新增部门'
  formState.value = {
    deptName: '',
    deptCode: '',
    parentId: selectedKeys.value[0] as any,
    deptType: currentDept.value?.deptType || 'ADMIN',
    defaultRoleCode: '',
    sortOrder: 0
  }
  drawerVisible.value = true
}

// 编辑
const handleEdit = () => {
  if (!currentDept.value) return
  isEdit.value = true
  drawerTitle.value = '编辑部门'
  formState.value = {
    deptName: currentDept.value.deptName,
    deptCode: currentDept.value.deptCode,
    parentId: currentDept.value.parentId,
    deptType: currentDept.value.deptType || 'ADMIN',
    defaultRoleCode: currentDept.value.defaultRoleCode,
    sortOrder: currentDept.value.sortOrder
  }
  drawerVisible.value = true
}

// 删除
const handleDelete = () => {
  if (!currentDept.value) return
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除部门"${currentDept.value.deptName}"吗？删除后不可恢复。`,
    okText: '删除',
    okType: 'danger',
    onOk: async () => {
      try {
        await deleteDept(currentDept.value!.id!)
        message.success('删除成功')
        selectedKeys.value = []
        currentDept.value = null
        members.value = []
        await fetchDeptTree()
      } catch (e: any) {
        message.error(e.message || '删除失败')
      }
    }
  })
}

// 提交
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    submitting.value = true

    if (isEdit.value && currentDept.value) {
      await updateDept(currentDept.value.id!, formState.value)
      message.success('更新成功')
    } else {
      await createDept(formState.value)
      message.success('创建成功')
    }

    drawerVisible.value = false
    await fetchDeptTree()
    // 刷新当前选中的部门
    if (selectedKeys.value.length > 0) {
      const node = findNodeByKey(treeData.value, selectedKeys.value[0])
      if (node) {
        currentDept.value = node.deptData
        const deptIds = getAllChildDeptIds(node)
        await fetchMembers(deptIds)
      }
    }
  } catch (error: any) {
    if (error.errorFields) return
    message.error('操作失败')
  } finally {
    submitting.value = false
  }
}

// 关闭抽屉
const handleClose = () => {
  formRef.value?.resetFields()
  drawerVisible.value = false
}

onMounted(async () => {
  await fetchRoles()
  await fetchDeptTree()
})
</script>

<template>
  <div class="page-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2 class="page-title">组织架构</h2>
      <div class="page-header-actions">
        <Button type="primary" @click="handleAdd">
          <PlusOutlined /> 新增部门
        </Button>
      </div>
    </div>

    <!-- 左右布局 -->
    <Row :gutter="16" class="main-content">
      <!-- 左侧部门树 -->
      <Col :span="6">
        <div class="card">
          <div class="card-title">
            <TeamOutlined />
            部门列表
            <Button size="small" style="margin-left: auto;" @click="fetchDeptTree">
              <ReloadOutlined />
            </Button>
          </div>
          <Spin :spinning="loading">
            <Tree
              v-if="treeData.length > 0"
              :tree-data="treeData"
              :selected-keys="selectedKeys"
              :expanded-keys="expandedKeys"
              :block-node="true"
              show-line
              @select="handleSelect"
              @expand="(keys: any) => expandedKeys = keys as string[]"
            >
              <template #title="{ title, deptData }">
                <Space>
                  <span>{{ title }}</span>
                  <Tag v-if="deptData.deptType" size="small" :color="getDeptTypeColor(deptData.deptType)">
                    {{ getDeptTypeLabel(deptData.deptType) }}
                  </Tag>
                </Space>
              </template>
            </Tree>
            <Empty v-else description="暂无部门数据" />
          </Spin>
        </div>
      </Col>

      <!-- 右侧详情 -->
      <Col :span="18">
        <template v-if="currentDept">
          <!-- 部门信息 -->
          <div class="card">
            <div class="card-title">
              <span>{{ currentDept.deptName }}</span>
              <StatusTag :status="currentDept.status || 'ACTIVE'" />
              <Space style="margin-left: auto;">
                <Button @click="handleEdit">
                  <EditOutlined /> 编辑
                </Button>
                <Button danger @click="handleDelete">
                  <DeleteOutlined /> 删除
                </Button>
              </Space>
            </div>
            <Descriptions :column="4" size="small">
              <Descriptions.Item label="部门编码">{{ currentDept.deptCode || '-' }}</Descriptions.Item>
              <Descriptions.Item label="部门类型">
                <Tag :color="getDeptTypeColor(currentDept.deptType || 'ADMIN')">
                  {{ getDeptTypeLabel(currentDept.deptType || 'ADMIN') }}
                </Tag>
              </Descriptions.Item>
              <Descriptions.Item label="默认角色">{{ currentDept.defaultRoleCode || '-' }}</Descriptions.Item>
              <Descriptions.Item label="排序">{{ currentDept.sortOrder || 0 }}</Descriptions.Item>
            </Descriptions>
          </div>

          <!-- 人员清单 -->
          <div class="table-card" style="margin-top: 16px;">
            <div class="card-title">
              <TeamOutlined />
              人员清单（含子部门）
              <Tag color="blue">{{ pagination.total }} 人</Tag>
            </div>
            <Table
              :columns="columns"
              :data-source="paginatedData"
              :loading="membersLoading"
              :row-key="(record: any) => record.id"
              :pagination="false"
              size="small"
            >
              <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'status'">
                  <StatusTag :status="record.status" />
                </template>
                <template v-else-if="column.key === 'userType'">
                  {{ record.userType === 'ENTERPRISE' ? '企业员工' : record.userType === 'PROJECT_STAFF' ? '项目员工' : record.userType }}
                </template>
                <template v-else-if="column.key === 'action'">
                  <TableActions
                    show-view
                    @view="() => {}"
                  />
                </template>
              </template>
            </Table>
            <Pagination
              v-model:current="pagination.current"
              v-model:pageSize="pagination.pageSize"
              :total="pagination.total"
              @change="handlePageChange"
            />
          </div>
        </template>

        <div v-else class="card" style="min-height: calc(100vh - 200px); display: flex; align-items: center; justify-content: center;">
          <Empty description="请选择左侧部门查看详情" />
        </div>
      </Col>
    </Row>

    <!-- 新增/编辑抽屉 -->
    <Drawer
      v-model:open="drawerVisible"
      :title="drawerTitle"
      :width="480"
      @close="handleClose"
    >
      <Form
        ref="formRef"
        :model="formState"
        layout="vertical"
        :rules="{
          deptName: [{ required: true, message: '请输入部门名称', trigger: 'blur' }]
        }"
      >
        <Form.Item label="上级部门" name="parentId">
          <TreeSelect
            v-model:value="formState.parentId"
            :tree-data="treeData"
            :field-names="{ children: 'children', label: 'title', value: 'key' }"
            placeholder="请选择上级部门（留空为顶级）"
            allow-clear
            style="width: 100%"
          />
        </Form.Item>
        <Form.Item label="部门名称" name="deptName" required>
          <Input v-model:value="formState.deptName" placeholder="请输入部门名称" />
        </Form.Item>
        <Form.Item label="部门编码" name="deptCode">
          <Input v-model:value="formState.deptCode" placeholder="请输入部门编码（可选）" />
        </Form.Item>
        <Form.Item label="部门类型" name="deptType">
          <Select v-model:value="formState.deptType" :options="deptTypeOptions" placeholder="请选择部门类型" />
        </Form.Item>
        <Form.Item label="默认角色" name="defaultRoleCode">
          <Select
            v-model:value="formState.defaultRoleCode"
            :options="roles.map(r => ({ value: r.code, label: r.name }))"
            placeholder="请选择默认角色"
            allow-clear
          />
        </Form.Item>
        <Form.Item label="排序" name="sortOrder">
          <InputNumber v-model:value="formState.sortOrder" :min="0" style="width: 100%" />
        </Form.Item>
      </Form>
      <template #footer>
        <Space>
          <Button @click="handleClose">取消</Button>
          <Button type="primary" :loading="submitting" @click="handleSubmit">确定</Button>
        </Space>
      </template>
    </Drawer>
  </div>
</template>

<style scoped>
.page-container {
  padding: 16px;
}

.main-content {
  margin-top: 0;
}

.card {
  background: #fff;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  padding: 16px;
}

.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  font-weight: 500;
}

:deep(.ant-tree-node-content-wrapper) {
  padding: 4px 8px;
}
</style>
