/**
 * 角色权限管理控制器
 * @file rolePermissionController.js
 * @description 处理角色权限管理相关的请求
 */

const { Role, MenuPermission, User, Permission } = require('../models');
const { Op } = require('sequelize');
const logger = require('../utils/logger');

/**
 * 获取所有角色
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getAllRoles = async (req, res) => {
  try {
    const { page = 1, pageSize = 10, search = '' } = req.query;
    const offset = (page - 1) * pageSize;
    const limit = parseInt(pageSize);

    // 构建查询条件
    const whereCondition = {};
    if (search) {
      whereCondition[Op.or] = [
        { name: { [Op.like]: `%${search}%` } },
        { description: { [Op.like]: `%${search}%` } }
      ];
    }

    const { count, rows } = await Role.findAndCountAll({
      where: whereCondition,
      include: [
        {
          model: MenuPermission,
          as: 'menuPermissions',
          through: { attributes: [] }
        },
        {
          model: Permission,
          as: 'permissions',
          through: { attributes: [] }
        }
      ],
      order: [['created_at', 'DESC']],
      offset,
      limit
    });

    res.status(200).json({
      success: true,
      data: {
        list: rows,
        pagination: {
          current: parseInt(page),
          pageSize: limit,
          total: count,
          pages: Math.ceil(count / limit)
        }
      },
      message: '获取角色列表成功'
    });
  } catch (error) {
    console.error('获取角色列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取角色列表失败',
      error: error.message
    });
  }
};

/**
 * 获取角色详情
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getRoleById = async (req, res) => {
  try {
    const { id } = req.params;

    const role = await Role.findByPk(id, {
      include: [
        {
          model: MenuPermission,
          as: 'menuPermissions',
          through: { attributes: [] },
          order: [['sort_order', 'ASC']]
        },
        {
          model: User,
          as: 'users',
          attributes: ['id', 'username', 'email'],
          through: { attributes: [] }
        }
      ]
    });

    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    res.status(200).json({
      success: true,
      data: role,
      message: '获取角色详情成功'
    });
  } catch (error) {
    console.error('获取角色详情失败:', error);
    res.status(500).json({
      success: false,
      message: '获取角色详情失败',
      error: error.message
    });
  }
};

/**
 * 创建角色
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.createRole = async (req, res) => {
  try {
    const {
      name,
      description,
      status = true,
      menuIds = []
    } = req.body;

    // 验证必填字段
    if (!name) {
      return res.status(400).json({
        success: false,
        message: '角色名称为必填项'
      });
    }

    // 检查角色名称是否重复
    const existingRole = await Role.findOne({
      where: { name }
    });

    if (existingRole) {
      return res.status(400).json({
        success: false,
        message: '角色名称已存在'
      });
    }

    // 创建角色
    const role = await Role.create({
      name,
      description,
      status
    });

    // 设置菜单权限
    if (menuIds && menuIds.length > 0) {
      await role.setMenuPermissions(menuIds);
    }

    // 重新获取角色信息（包含关联数据）
    const roleWithPermissions = await Role.findByPk(role.id, {
      include: [
        {
          model: MenuPermission,
          as: 'menuPermissions',
          through: { attributes: [] }
        }
      ]
    });

    res.status(201).json({
      success: true,
      data: roleWithPermissions,
      message: '角色创建成功'
    });
  } catch (error) {
    console.error('创建角色失败:', error);
    res.status(500).json({
      success: false,
      message: '创建角色失败',
      error: error.message
    });
  }
};

/**
 * 更新角色
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.updateRole = async (req, res) => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    const role = await Role.findByPk(id);
    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    // 如果更新名称，检查是否重复
    if (updateData.name && updateData.name !== role.name) {
      const existingRole = await Role.findOne({
        where: {
          name: updateData.name,
          id: { [Op.ne]: id }
        }
      });

      if (existingRole) {
        return res.status(400).json({
          success: false,
          message: '角色名称已存在'
        });
      }
    }

    // 更新角色基本信息
    const { menuIds, ...roleData } = updateData;
    await role.update(roleData);

    // 更新菜单权限
    if (menuIds !== undefined) {
      await role.setMenuPermissions(menuIds || []);
    }

    // 重新获取角色信息（包含关联数据）
    const updatedRole = await Role.findByPk(id, {
      include: [
        {
          model: MenuPermission,
          as: 'menuPermissions',
          through: { attributes: [] }
        }
      ]
    });

    res.status(200).json({
      success: true,
      data: updatedRole,
      message: '角色更新成功'
    });
  } catch (error) {
    console.error('更新角色失败:', error);
    res.status(500).json({
      success: false,
      message: '更新角色失败',
      error: error.message
    });
  }
};

/**
 * 删除角色
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.deleteRole = async (req, res) => {
  try {
    const { id } = req.params;

    const role = await Role.findByPk(id);
    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    // 检查是否有用户使用该角色
    const userCount = await User.count({
      where: { roles: id }
    });

    if (userCount > 0) {
      return res.status(400).json({
        success: false,
        message: '该角色下还有用户，无法删除'
      });
    }

    await role.destroy();

    res.status(200).json({
      success: true,
      message: '角色删除成功'
    });
  } catch (error) {
    console.error('删除角色失败:', error);
    res.status(500).json({
      success: false,
      message: '删除角色失败',
      error: error.message
    });
  }
};

/**
 * 获取角色的菜单权限
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getRoleMenuPermissions = async (req, res) => {
  try {
    const { roleId } = req.params;

    const role = await Role.findByPk(roleId, {
      include: [
        {
          model: MenuPermission,
          as: 'menuPermissions',
          through: { attributes: [] },
          order: [['sort_order', 'ASC']]
        }
      ]
    });

    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    res.status(200).json({
      success: true,
      data: {
        roleId: role.id,
        roleName: role.name,
        permissions: role.menuPermissions
      },
      message: '获取角色菜单权限成功'
    });
  } catch (error) {
    console.error('获取角色菜单权限失败:', error);
    res.status(500).json({
      success: false,
      message: '获取角色菜单权限失败',
      error: error.message
    });
  }
};

/**
 * 设置角色的菜单权限
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.setRoleMenuPermissions = async (req, res) => {
  try {
    const { roleId } = req.params;
    const { menuIds } = req.body;

    const role = await Role.findByPk(roleId);
    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    // 设置菜单权限
    await role.setMenuPermissions(menuIds || []);

    res.status(200).json({
      success: true,
      message: '设置角色菜单权限成功'
    });
  } catch (error) {
    console.error('设置角色菜单权限失败:', error);
    res.status(500).json({
      success: false,
      message: '设置角色菜单权限失败',
      error: error.message
    });
  }
};

/**
 * 获取所有菜单权限（用于权限分配）
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getAllMenuPermissions = async (req, res) => {
  try {
    const menus = await MenuPermission.findAll({
      order: [['sort_order', 'ASC'], ['id', 'ASC']]
    });

    // 构建树形结构
    const menuTree = buildMenuTree(menus);

    res.status(200).json({
      success: true,
      data: menuTree,
      message: '获取菜单权限列表成功'
    });
  } catch (error) {
    console.error('获取菜单权限列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取菜单权限列表失败',
      error: error.message
    });
  }
};

/**
 * 构建菜单树形结构
 * @param {Array} menus - 菜单数组
 * @returns {Array} 树形结构的菜单数组
 */
function buildMenuTree(menus) {
  const menuMap = new Map();
  const rootMenus = [];

  // 创建菜单映射
  menus.forEach(menu => {
    menuMap.set(menu.id, {
      ...menu.toJSON(),
      children: []
    });
  });

  // 构建树形结构
  menus.forEach(menu => {
    const menuItem = menuMap.get(menu.id);
    if (menu.parent_id) {
      const parent = menuMap.get(menu.parent_id);
      if (parent) {
        parent.children.push(menuItem);
      }
    } else {
      rootMenus.push(menuItem);
    }
  });

  return rootMenus;
}

/**
 * 获取所有权限（用于权限分配）
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getAllPermissions = async (req, res) => {
  try {
    const { module, action } = req.query;
    
    const whereCondition = {};
    if (module) {
      whereCondition.module = module;
    }
    if (action) {
      whereCondition.action = action;
    }

    const permissions = await Permission.findAll({
      where: whereCondition,
      order: [['module', 'ASC'], ['action', 'ASC'], ['id', 'ASC']]
    });

    // 按模块分组
    const groupedPermissions = permissions.reduce((acc, permission) => {
      const module = permission.module;
      if (!acc[module]) {
        acc[module] = [];
      }
      acc[module].push(permission);
      return acc;
    }, {});

    res.status(200).json({
      success: true,
      data: {
        permissions: permissions,
        groupedPermissions: groupedPermissions,
        modules: Object.keys(groupedPermissions)
      },
      message: '获取权限列表成功'
    });
  } catch (error) {
    console.error('获取权限列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取权限列表失败',
      error: error.message
    });
  }
};

/**
 * 获取角色的功能权限
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getRolePermissions = async (req, res) => {
  try {
    const { roleId } = req.params;

    const role = await Role.findByPk(roleId, {
      include: [
        {
          model: Permission,
          as: 'permissions',
          through: { attributes: [] },
          order: [['module', 'ASC'], ['action', 'ASC']]
        }
      ]
    });

    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    // 按模块分组权限
    const groupedPermissions = role.permissions.reduce((acc, permission) => {
      const module = permission.module;
      if (!acc[module]) {
        acc[module] = [];
      }
      acc[module].push(permission);
      return acc;
    }, {});

    res.status(200).json({
      success: true,
      data: {
        roleId: role.id,
        roleName: role.name,
        permissions: role.permissions,
        groupedPermissions: groupedPermissions,
        modules: Object.keys(groupedPermissions)
      },
      message: '获取角色权限成功'
    });
  } catch (error) {
    console.error('获取角色权限失败:', error);
    res.status(500).json({
      success: false,
      message: '获取角色权限失败',
      error: error.message
    });
  }
};

/**
 * 设置角色的功能权限
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.setRolePermissions = async (req, res) => {
  try {
    const { roleId } = req.params;
    const { permissionIds } = req.body;

    const role = await Role.findByPk(roleId);
    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    // 设置权限
    await role.setPermissions(permissionIds || []);

    // 重新获取角色信息（包含关联数据）
    const updatedRole = await Role.findByPk(roleId, {
      include: [
        {
          model: Permission,
          as: 'permissions',
          through: { attributes: [] }
        }
      ]
    });

    res.status(200).json({
      success: true,
      data: updatedRole,
      message: '设置角色权限成功'
    });
  } catch (error) {
    console.error('设置角色权限失败:', error);
    res.status(500).json({
      success: false,
      message: '设置角色权限失败',
      error: error.message
    });
  }
};

/**
 * 获取权限模块列表
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.getPermissionModules = async (req, res) => {
  try {
    const modules = await Permission.findAll({
      attributes: ['module'],
      group: ['module'],
      order: [['module', 'ASC']]
    });

    res.status(200).json({
      success: true,
      data: modules.map(m => m.module),
      message: '获取权限模块列表成功'
    });
  } catch (error) {
    console.error('获取权限模块列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取权限模块列表失败',
      error: error.message
    });
  }
};

/**
 * 切换角色状态
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.toggleRoleStatus = async (req, res) => {
  try {
    const { id } = req.params;
    const { status } = req.body;

    const role = await Role.findByPk(id);
    if (!role) {
      return res.status(404).json({
        success: false,
        message: '角色不存在'
      });
    }

    // 更新状态
    await role.update({ status });

    res.status(200).json({
      success: true,
      data: {
        id: role.id,
        name: role.name,
        status: role.status
      },
      message: `角色${status ? '启用' : '禁用'}成功`
    });
  } catch (error) {
    console.error('切换角色状态失败:', error);
    res.status(500).json({
      success: false,
      message: '切换角色状态失败',
      error: error.message
    });
  }
};
