<template>
  <el-dialog title="选择接收者" v-model="visible" width="700px" append-to-body @close="handleClose">
    <el-tabs v-model="activeTab">
      <el-tab-pane label="按部门" name="dept">
        <el-tree
          ref="deptTreeRef"
          :data="deptTree"
          :props="deptTreeProps"
          show-checkbox
          node-key="id"
          :default-checked-keys="selectedUserIds"
          @check="handleDeptCheck"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span>
                <el-icon v-if="data.type === 'dept'"><OfficeBuilding /></el-icon>
                <el-icon v-else><User /></el-icon>
                {{ node.label }}
              </span>
              <span v-if="data.type === 'user'" class="user-account">{{ data.userName }}</span>
            </span>
          </template>
        </el-tree>
      </el-tab-pane>
      
      <el-tab-pane label="按角色" name="role">
        <div class="role-list">
          <el-checkbox-group v-model="selectedRoles" @change="handleRoleChange">
            <div v-for="role in roleList" :key="role.roleId" class="role-item">
              <el-checkbox :value="role.roleId">
                <span class="role-name">{{ role.roleName }}</span>
                <el-tag size="small" type="info">{{ getRoleUserCount(role.roleId) }}人</el-tag>
              </el-checkbox>
            </div>
          </el-checkbox-group>
        </div>
      </el-tab-pane>
    </el-tabs>
    
    <div class="selected-info">
      <el-tag type="success">已选择 {{ selectedUsers.length }} 人</el-tag>
      <el-button type="primary" link @click="clearSelection">清空</el-button>
    </div>
    
    <template #footer>
      <el-button @click="visible = false">取消</el-button>
      <el-button type="primary" @click="confirm">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup name="SelectUserDialog">
import { OfficeBuilding, User } from '@element-plus/icons-vue'
import { listDept } from "@/api/system/dept"
import { listRole } from "@/api/system/role"
import { listUser } from "@/api/system/user"

const emit = defineEmits(['confirm'])

const visible = ref(false)
const activeTab = ref('dept')
const deptList = ref([])
const roleList = ref([])
const userList = ref([])
const deptTree = ref([])
const deptTreeRef = ref(null)
const deptTreeProps = {
  children: 'children',
  label: 'label'
}
const selectedUserIds = ref([])
const selectedRoles = ref([])

const selectedUsers = computed(() => {
  return userList.value.filter(u => selectedUserIds.value.includes(u.userId))
})

function open(preSelectedIds = []) {
  visible.value = true
  selectedUserIds.value = [...preSelectedIds]
  loadData()
}

async function loadData() {
  await Promise.all([
    loadDeptList(),
    loadRoleList(),
    loadUserList()
  ])
  buildDeptTree()
}

async function loadDeptList() {
  const response = await listDept()
  deptList.value = response.data || []
}

async function loadRoleList() {
  const response = await listRole({ pageNum: 1, pageSize: 100 })
  roleList.value = response.rows || []
}

async function loadUserList() {
  const response = await listUser({ pageNum: 1, pageSize: 1000 })
  userList.value = response.rows || []
}

function buildDeptTree() {
  const tree = []
  const deptMap = new Map()
  
  deptList.value.forEach(dept => {
    const node = {
      id: `dept_${dept.deptId}`,
      label: dept.deptName,
      type: 'dept',
      deptId: dept.deptId,
      parentId: dept.parentId,
      children: []
    }
    deptMap.set(dept.deptId, node)
  })
  
  userList.value.forEach(user => {
    if (user.deptId && deptMap.has(user.deptId)) {
      deptMap.get(user.deptId).children.push({
        id: `user_${user.userId}`,
        label: user.nickName,
        type: 'user',
        userId: user.userId,
        userName: user.userName
      })
    }
  })
  
  deptMap.forEach(node => {
    if (node.parentId === 0) {
      tree.push(node)
    } else if (deptMap.has(node.parentId)) {
      deptMap.get(node.parentId).children.push(node)
    }
  })
  
  deptTree.value = tree
}

function handleDeptCheck() {
  const checkedNodes = deptTreeRef.value.getCheckedNodes()
  selectedUserIds.value = checkedNodes
    .filter(node => node.type === 'user')
    .map(node => node.userId)
}

function handleRoleChange() {
  const userIds = new Set(selectedUserIds.value)
  
  selectedRoles.value.forEach(roleId => {
    const users = userList.value.filter(u => 
      u.roles && u.roles.some(r => r.roleId === roleId)
    )
    users.forEach(u => userIds.add(u.userId))
  })
  
  selectedUserIds.value = Array.from(userIds)
}

function getRoleUserCount(roleId) {
  return userList.value.filter(u => 
    u.roles && u.roles.some(r => r.roleId === roleId)
  ).length
}

function clearSelection() {
  selectedUserIds.value = []
  selectedRoles.value = []
  if (deptTreeRef.value) {
    deptTreeRef.value.setCheckedKeys([])
  }
}

function confirm() {
  emit('confirm', selectedUsers.value)
  visible.value = false
}

function handleClose() {
  clearSelection()
}

defineExpose({ open })
</script>

<style lang="scss" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
  
  .el-icon {
    margin-right: 6px;
    color: #909399;
  }
  
  .user-account {
    font-size: 12px;
    color: #909399;
  }
}

.role-list {
  max-height: 400px;
  overflow-y: auto;
  
  .role-item {
    padding: 12px;
    border-bottom: 1px solid #f0f0f0;
    
    &:last-child {
      border-bottom: none;
    }
    
    .role-name {
      margin-right: 8px;
    }
  }
}

.selected-info {
  margin-top: 16px;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
</style>
