<template>
  <AdminLayout 
    title="系统管理" 
    subtitle="管理用户、角色、权限、部门等系统信息"
  >
    <div class="user-manage">
      <div class="header">
        <h2>用户管理</h2>
        <el-button type="primary" @click="handleAdd">
          <el-icon><Plus /></el-icon>
          新增用户
        </el-button>
      </div>

      <el-table 
        :data="userList" 
        style="width: 100%" 
        v-loading="loading"
        border
        stripe
        row-key="userID"
      >
        <el-table-column prop="username" label="用户名" min-width="120" />
        <el-table-column prop="email" label="邮箱" min-width="180" />
        <el-table-column prop="phone" label="手机号" min-width="120" />
        <el-table-column prop="realName" label="真实姓名" min-width="100" />
        <el-table-column prop="nickname" label="昵称" min-width="100" />
        <el-table-column label="部门-角色" min-width="200">
          <template #default="{ row }">
            <div class="tag-container">
              <el-tag 
                v-for="(combo, index) in row.deptRoleCombos" 
                :key="index"
                type="primary"
                size="small"
                style="margin: 2px"
              >
                {{ combo }}
              </el-tag>
              <span v-if="!row.deptRoleCombos || row.deptRoleCombos.length === 0" style="color: #909399;">未分配</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="80">
          <template #default="{ row }">
            <el-tag :type="row.status === 0 ? 'success' : 'danger'">
              {{ row.status === 0 ? '正常' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180" />
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button 
              type="primary" 
              size="small" 
              @click="handleEdit(row)"
              link
            >
              编辑
            </el-button>
            <el-button 
              type="primary" 
              size="small" 
              @click="handleBindDeptRole(row)"
              link
            >
              绑定部门角色
            </el-button>
            <el-button 
              type="danger" 
              size="small" 
              @click="handleDelete(row)"
              link
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页组件 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pageParam.pageNumber"
          v-model:page-size="pageParam.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>

      <!-- 新增/编辑用户对话框 -->
      <el-dialog
        v-model="userDialogVisible"
        :title="isEdit ? '编辑用户' : '新增用户'"
        width="600px"
        @close="resetForm"
      >
        <el-form
          ref="userFormRef"
          :model="currentUser"
          :rules="userFormRules"
          label-width="100px"
        >
          <el-form-item label="用户名" prop="username">
            <el-input v-model="currentUser.username" placeholder="请输入用户名" />
          </el-form-item>
          <el-form-item label="密码" prop="password" v-if="!isEdit">
            <el-input 
              v-model="currentUser.password" 
              type="password" 
              placeholder="请输入密码"
              show-password
            />
          </el-form-item>
          <el-form-item label="邮箱" prop="email">
            <el-input v-model="currentUser.email" placeholder="请输入邮箱" />
          </el-form-item>
          <el-form-item label="手机号" prop="phone">
            <el-input v-model="currentUser.phone" placeholder="请输入手机号" />
          </el-form-item>
          <el-form-item label="真实姓名" prop="realName">
            <el-input v-model="currentUser.fullName" placeholder="请输入真实姓名" />
          </el-form-item>
          <el-form-item label="昵称" prop="nickname">
            <el-input v-model="currentUser.username" placeholder="请输入昵称" />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-radio-group v-model="currentUser.status">
              <el-radio :value="0">正常</el-radio>
              <el-radio :value="1">禁用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button @click="userDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitUserForm" :loading="submitting">
            确定
          </el-button>
        </template>
      </el-dialog>

      <!-- 部门角色选择器 -->
      <GenericSelector
        v-model:visible="showDeptRoleSelector"
        :title="`绑定部门角色 - ${currentUser.username || ''}`"
        left-title="可选的部门角色组合"
        right-title="已选的部门角色"
        :fetch-available-api="fetchAllDeptRoles"
        :fetch-selected-api="fetchUserDeptRoles"
        :filter-selected="filterDeptRoles"
        :item-config="{ id: 'combinedId', label: 'displayName', sublabel: 'deptDescription' }"
        :use-tree="true"
        :tree-transform="transformDeptRolesToTree"
        :tree-props="{ children: 'children', label: 'displayName', id: 'combinedId' }"
        :only-leaf-selectable="true"
        unit-name="个"
        search-placeholder="搜索部门或角色..."
        @confirm="handleDeptRoleConfirm"
        @cancel="closeDeptRoleSelector"
      />
    </div>
  </AdminLayout>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { userApi, deptApi } from '@/apis/system';
import type { SysUser, PageParam, UserVO, UserDeptRoleVO, SysUserDeptRole } from '@/types';
import { AdminLayout } from '@/views/admin';
import { GenericSelector } from '@/components/base';

defineOptions({
  name: 'UserManageView'
});

const loading = ref(false);
const submitting = ref(false);
const binding = ref(false);

const userList = ref<UserVO[]>([]);

// 分页参数
const pageParam = ref<PageParam>({
  pageNumber: 1,
  pageSize: 10
});
const total = ref(0);

const userDialogVisible = ref(false);
const isEdit = ref(false);

const userFormRef = ref<FormInstance>();

const currentUser = ref<UserVO & { password?: string }>({
  status: 0
});

// 保存原始用户数据，用于比较变更
const originalUser = ref<UserVO & { password?: string }>({});

// 选择器控制
const showDeptRoleSelector = ref(false);
const currentBindingUserId = ref<string>();

// 获取所有部门角色组合的接口
async function fetchAllDeptRoles() {
  const result = await deptApi.getDeptRoleList({} as SysUserDeptRole);
  if (result.success) {
    const deptRoleList = result.dataList || [];
    // 转换为带有combinedId和displayName的格式
    const transformed = deptRoleList
      .filter(item => item.deptID && item.roleID)
      .map(item => ({
        ...item,
        combinedId: `${item.deptID}-${item.roleID}`,
        displayName: `${item.deptName || ''} - ${item.roleName || ''}`
      }));
    return { ...result, dataList: transformed };
  }
  return result;
}

// 获取用户已选的部门角色接口
async function fetchUserDeptRoles() {
  if (!currentBindingUserId.value) {
    return { 
      success: true, 
      dataList: [],
      code: 200,
      message: '',
      login: true,
      auth: true
    };
  }
  const result = await userApi.getUserDeptRole({ userID: currentBindingUserId.value } as SysUserDeptRole);
  if (result.success) {
    const selectedList = result.dataList || [];
    // 转换为带有combinedId和displayName的格式
    const transformed = selectedList.map(item => ({
      ...item,
      combinedId: `${item.deptID}-${item.roleID}`,
      displayName: `${item.deptName || ''} - ${item.roleName || ''}`
    }));
    return { ...result, dataList: transformed };
  }
  return result;
}

// 过滤已选项的方法
function filterDeptRoles(available: any[], selected: any[]) {
  const selectedIds = new Set(selected.map(item => item.combinedId));
  return available.filter(item => !selectedIds.has(item.combinedId));
}

// 将部门角色扁平数据转换为树形结构
function transformDeptRolesToTree(flatData: any[]) {
  if (!flatData || flatData.length === 0) {
    return [];
  }
  
  // 按部门分组
  const deptMap = new Map<string, any>();
  const tree: any[] = [];
  
  flatData.forEach(item => {
    if (!item.deptID) return;
    
    if (!deptMap.has(item.deptID)) {
      // 创建部门节点
      deptMap.set(item.deptID, {
        combinedId: item.deptID,
        displayName: item.deptName || '',
        deptID: item.deptID,
        deptName: item.deptName,
        parentID: item.parentID,
        deptPath: item.deptPath,
        children: [],
        isDept: true // 标记这是部门节点
      });
    }
    
    // 添加角色到部门的children中
    const deptNode = deptMap.get(item.deptID);
    if (deptNode && item.roleID) {
      deptNode.children.push({
        ...item,
        isDept: false // 标记这是角色节点
      });
    }
  });
  
  // 构建树形结构
  const allDepts = Array.from(deptMap.values());
  const deptTreeMap = new Map<string, any>();
  
  // 初始化所有部门节点
  allDepts.forEach(dept => {
    deptTreeMap.set(dept.deptID, { ...dept });
  });
  
  // 构建部门层级关系
  allDepts.forEach(dept => {
    const node = deptTreeMap.get(dept.deptID);
    if (!node) return;
    
    if (!dept.parentID || dept.parentID === '0' || dept.parentID === '') {
      // 根部门
      tree.push(node);
    } else {
      // 子部门
      const parent = deptTreeMap.get(dept.parentID);
      if (parent) {
        if (!parent.children) {
          parent.children = [];
        }
        // 将角色节点添加到部门节点之前
        const roles = node.children || [];
        node.children = [];
        parent.children.push(node);
        // 将角色添加到部门的children末尾
        node.children = roles;
      } else {
        // 找不到父节点，作为根节点
        tree.push(node);
      }
    }
  });
  
  return tree;
}

const userFormRules: FormRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
  ],
  email: [
    { required: true, message: '请输入邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
  ]
};


onMounted(() => {
  loadUsers();
});

// 合并同一用户的多个部门角色（部门-角色是绑定关系）
function mergeUserDeptRoles(users: UserVO[]): UserVO[] {
  const userMap = new Map<string, UserVO>();
  
  users.forEach(user => {
    const userId = user.id || user.userID;
    if (!userId) return;
    
    // 生成部门-角色组合字符串
    const deptRoleCombo = (user.deptName && user.roleName) 
      ? `${user.deptName}-${user.roleName}` 
      : '';
    
    if (!userMap.has(userId)) {
      // 首次遇到该用户，初始化
      userMap.set(userId, {
        ...user,
        deptRoleCombos: deptRoleCombo ? [deptRoleCombo] : []
      });
    } else {
      // 已存在该用户，合并部门-角色组合
      const existingUser = userMap.get(userId)!;
      
      // 添加部门-角色组合（去重）
      if (deptRoleCombo && !existingUser.deptRoleCombos?.includes(deptRoleCombo)) {
        existingUser.deptRoleCombos = [...(existingUser.deptRoleCombos || []), deptRoleCombo];
      }
    }
  });
  
  return Array.from(userMap.values());
}

async function loadUsers() {
  try {
    loading.value = true;
    const result = await userApi.getUserPage(pageParam.value);
    if (result.success) {
      const rawUsers = result.dataList || [];
      // 合并同一用户的多个部门角色
      userList.value = mergeUserDeptRoles(rawUsers);
      // 注意：由于合并了数据，total应该是去重后的用户数量
      // 但是后端返回的total是原始记录数，这里需要调整
      // 如果后端无法修改，我们需要重新计算total
      total.value = userList.value.length;
    }
  } catch (error) {
    console.error('加载用户列表失败:', error);
    ElMessage.error('加载用户列表失败');
  } finally {
    loading.value = false;
  }
}

// 不再需要预加载，由GenericSelector在打开时自动调用接口加载

function handleAdd() {
  isEdit.value = false;
  currentUser.value = { status: 0 };
  originalUser.value = {};
  userDialogVisible.value = true;
}

function handleEdit(row: UserVO) {
  isEdit.value = true;
  currentUser.value = { ...row };
  // 保存原始数据用于比较
  originalUser.value = { ...row };
  userDialogVisible.value = true;
}

async function handleDelete(row: UserVO) {
  try {
    await ElMessageBox.confirm(
      `确定要删除用户"${row.username}"吗？`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    );

    const result = await userApi.deleteUser({ id: row.id } as SysUser);
    if (result.success) {
      ElMessage.success('删除成功');
      loadUsers();
    } else {
      ElMessage.error(result.message || '删除失败');
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除用户失败:', error);
      ElMessage.error('删除失败');
    }
  }
}

function handleBindDeptRole(row: UserVO) {
  currentBindingUserId.value = row.id;
  currentUser.value = { ...row };
  showDeptRoleSelector.value = true;
}

// 部门角色选择确认 - 在confirm时提交请求
async function handleDeptRoleConfirm(items: any[]) {
  if (!currentBindingUserId.value) {
    ElMessage.error('用户信息不完整');
    return;
  }

  // 【限制】检查是否只选择了一个部门-角色
  if (items.length === 0) {
    ElMessage.warning('请选择一个部门角色');
    return;
  }
  
  if (items.length > 1) {
    ElMessage.error('一个用户只能绑定一个部门-角色，请选择且仅选择一个');
    return;
  }

  try {
    binding.value = true;
    
    // 移除临时添加的字段，只保留原始字段
    const userDeptRoles: SysUserDeptRole[] = items.map(item => ({
      deptID: item.deptID,
      roleID: item.roleID,
      userID: currentBindingUserId.value
    }));
    
    // 构建 UserDeptRoleVO 对象（用于批量绑定）
    const userDeptRoleVO = {
      users: [{ id: currentBindingUserId.value } as SysUser],
      userDeptRoles: userDeptRoles
    } as UserDeptRoleVO;
    
    const result = await userApi.bindUserDeptRole(userDeptRoleVO);

    if (result.success) {
      ElMessage.success('成功绑定部门角色');
      showDeptRoleSelector.value = false;
      loadUsers();
    } else {
      ElMessage.error(result.message || '绑定失败');
    }
  } catch (error) {
    console.error('绑定失败:', error);
    ElMessage.error('绑定失败');
  } finally {
    binding.value = false;
  }
}

// 关闭部门角色选择器
function closeDeptRoleSelector() {
  currentBindingUserId.value = undefined;
}

// 获取修改过的字段
function getChangedFields(): Partial<SysUser> {
  const changed: Partial<SysUser> = { id: currentUser.value.id };
  
  // 比较每个字段，只包含修改过的字段
  Object.keys(currentUser.value).forEach((key) => {
    const currentValue = (currentUser.value as any)[key];
    const originalValue = (originalUser.value as any)[key];
    
    // 如果值发生变化，则添加到变更对象中
    if (currentValue !== originalValue) {
      (changed as any)[key] = currentValue;
    }
  });
  
  return changed;
}

async function submitUserForm() {
  if (!userFormRef.value) return;

  try {
    await userFormRef.value.validate();
    submitting.value = true;

    let result;
    if (isEdit.value) {
      // 只传入修改过的字段
      const changedData = getChangedFields();
      console.log('更新用户 - 修改的字段:', changedData);
      result = await userApi.updateUser(changedData as SysUser);
    } else {
      result = await userApi.createUser(currentUser.value as SysUser);
    }

    if (result.success) {
      ElMessage.success(isEdit.value ? '更新成功' : '创建成功');
      userDialogVisible.value = false;
      loadUsers();
    } else {
      ElMessage.error(result.message || (isEdit.value ? '更新失败' : '创建失败'));
    }
  } catch (error) {
    console.error('提交失败:', error);
  } finally {
    submitting.value = false;
  }
}

// submitBindForm 已合并到 handleDeptRoleConfirm 中

function resetForm() {
  userFormRef.value?.resetFields();
  originalUser.value = {};
}

function handlePageChange(page: number) {
  pageParam.value.pageNumber = page;
  loadUsers();
}

function handleSizeChange(size: number) {
  pageParam.value.pageSize = size;
  pageParam.value.pageNumber = 1; // 改变每页数量时，重置到第一页
  loadUsers();
}
</script>

<style lang="scss" scoped>
.user-manage {
  background: #FFFFFF;
  padding: 24px;
  border-radius: 14px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;

  h2 {
    margin: 0;
    font-size: 18px;
    font-weight: 500;
    color: #101828;
  }
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 24px;
}

.tag-container {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
</style>
