// 引入Express框架的核心模块，用于创建Web应用、定义路由以及处理HTTP请求等相关操作
var express = require('express');
// 创建一个Express路由器实例，方便以模块化的方式来定义一组相关的路由，便于在整个应用中进行有条理的路由管理
var router = express.Router();
// 引入Node.js的path模块，主要用于处理文件路径相关的操作，比如拼接模块的路径，以便准确地引入其他模块
var path = require("path");

// 获取自定义的验证模块，通过path.join方法将当前工作目录（process.cwd()）与相对路径（"/modules/authorization"）拼接起来，准确地引入该验证模块
// 这个验证模块通常用于验证用户的权限等情况，确保后续操作符合相应的安全和业务规则
var authorization = require(path.join(process.cwd(), "/modules/authorization"));

// 通过验证模块获取名为"RoleService"的角色管理模块，该模块应该封装了与角色相关的各种业务操作方法，例如角色的增删改查以及权限管理等功能
var roleServ = authorization.getService("RoleService");

// 定义处理获取角色列表的GET请求的路由，路径为根路径 "/"
router.get("/",
    // 参数验证中间件，当前这里直接调用next()，意味着暂时没有进行额外的参数验证逻辑，不过一般情况下可根据实际需求添加相关验证，比如分页参数等验证
    function (req, res, next) {
        next();
    },
    // 处理业务逻辑的中间件，用于获取所有角色的信息
    function (req, res, next) {
        // 调用roleServ角色管理模块的getAllRoles方法，该方法用于获取所有角色的相关数据，是一个异步操作
        // 如果在获取角色列表的过程中出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
        // 如果获取成功，则返回包含角色列表数据（result）的响应，状态码为200，并附带提示信息"获取成功"
        roleServ.getAllRoles(function (err, result) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(result, 200, "获取成功");
        })(req, res, next);
    }
);

// 定义处理创建角色的POST请求的路由，路径为 "/"
router.post("/",
    // 参数验证中间件，用于验证创建角色时请求体中必要参数是否存在
    function (req, res, next) {
        // 检查请求体中是否包含roleName字段，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色名称不能为空"
        if (!req.body.roleName) return res.sendResult(null, 400, "角色名称不能为空");
        // 参数验证通过后，将控制权传递给下一个中间件，继续后续的业务逻辑处理
        next();
    },
    // 处理业务逻辑的中间件，用于创建新的角色
    function (req, res, next) {
        // 构建一个包含角色名称（roleName）和角色描述（roleDesc）的对象，从请求体中获取相应的值
        roleServ.createRole({
            "roleName": req.body.roleName,
            "roleDesc": req.body.roleDesc
        }, function (err, role) {
            // 如果创建角色的操作出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
            if (err) return res.sendResult(null, 400, err);
            // 如果创建成功，则返回包含新创建角色信息（role）的响应，状态码为201，表示资源创建成功，并附带提示信息"创建成功"
            res.sendResult(role, 201, "创建成功");
        })(req, res, next);
    }
);

// 定义处理获取角色详情的GET请求的路由，路径中包含角色ID参数，格式为 "/:id"
router.get("/:id",
    // 参数验证中间件，用于验证角色ID参数的合法性
    function (req, res, next) {
        // 检查请求参数中的角色ID（req.params.id）是否存在，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色ID不能为空"
        if (!req.params.id) return res.sendResult(null, 400, "角色ID不能为空");
        // 进一步验证角色ID是否可以转换为数字类型，如果不能转换成功（即不是有效的数字），则返回错误响应，状态码同样为400，并附带提示信息"角色ID必须为数字"
        if (isNaN(parseInt(req.params.id))) res.sendResult(null, 400, "角色ID必须为数字");
        // 参数验证通过后，将控制权传递给下一个中间件，继续后续的业务逻辑处理
        next();
    },
    // 处理业务逻辑的中间件，用于获取指定角色的详细信息
    function (req, res, next) {
        // 调用roleServ角色管理模块的getRoleById方法，传入经过验证的角色ID（req.params.id），用于获取该角色的详细信息，这是一个异步操作
        // 如果在获取角色详情的过程中出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
        // 如果获取成功，则返回包含角色详细信息（result）的响应，状态码为200，并附带提示信息"获取成功"
        roleServ.getRoleById(
            req.params.id,
            function (err, result) {
                if (err) return res.sendResult(null, 400, err);
                res.sendResult(result, 200, "获取成功");
            }
        )(req, res, next);
    }
);

// 定义处理更新角色信息的PUT请求的路由，路径中包含角色ID参数，格式为 "/:id"
router.put("/:id",
    // 参数验证中间件，用于验证更新角色信息时必要参数的合法性
    function (req, res, next) {
        // 检查请求参数中的角色ID（req.params.id）是否存在，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色ID不能为空"
        if (!req.params.id) return res.sendResult(null, 400, "角色ID不能为空");
        // 验证角色ID是否可以转换为数字类型，如果不能转换成功（即不是有效的数字），则返回错误响应，状态码为400，并附带提示信息"角色ID必须为数字"
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "角色ID必须为数字");
        // 检查请求体中是否包含roleName字段，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色名称不能为空"
        if (!req.body.roleName) return res.sendResult(null, 400, "角色名称不能为空");
        // 参数验证通过后，将控制权传递给下一个中间件，继续后续的业务逻辑处理
        next();
    },
    // 处理业务逻辑的中间件，用于更新指定角色的信息
    function (req, res, next) {
        // 构建一个包含角色ID（id）、角色名称（roleName）和角色描述（roleDesc）的对象，用于传递给更新角色信息的方法
        roleServ.updateRole(
            {
                "id": req.params.id,
                "roleName": req.body.roleName,
                "roleDesc": req.body.roleDesc
            },
            function (err, result) {
                // 如果更新角色信息的操作出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
                if (err) return res.sendResult(null, 400, err);
                // 如果更新成功，则返回包含更新后角色信息（result）的响应，状态码为200，并附带提示信息"获取成功"（此处提示信息可能更改为"更新成功"更合适，可根据实际情况调整）
                res.sendResult(result, 200, "获取成功");
            }
        )(req, res, next);
    }
);

// 定义处理删除角色的DELETE请求的路由，路径中包含角色ID参数，格式为 "/:id"
router.delete("/:id",
    // 参数验证中间件，用于验证角色ID参数的合法性
    function (req, res, next) {
        // 检查请求参数中的角色ID（req.params.id）是否存在，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色ID不能为空"
        if (!req.params.id) return res.sendResult(null, 400, "角色ID不能为空");
        // 验证角色ID是否可以转换为数字类型，如果不能转换成功（即不是有效的数字），则返回错误响应，状态码为400，并附带提示信息"角色ID必须为数字"
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "角色ID必须为数字");
        // 参数验证通过后，将控制权传递给下一个中间件，继续后续的业务逻辑处理
        next();
    },
    // 处理业务逻辑的中间件，用于执行删除指定角色的操作
    function (req, res, next) {
        // 调用roleServ角色管理模块的deleteRole方法，传入经过验证的角色ID（req.params.id），用于删除该角色，这是一个异步操作
        // 如果在删除角色的过程中出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
        // 如果删除成功，则返回一个空数据的响应（因为角色已被删除），状态码为200，并附带提示信息"删除成功"
        roleServ.deleteRole(
            req.params.id,
            function (err, success) {
                if (err) return res.sendResult(null, 400, err);
                res.sendResult(null, 200, "删除成功");
            }
        )(req, res, next);
    }
);

// 定义处理为角色授权的POST请求的路由，路径中包含角色ID参数，格式为 "/:id/rights"
router.post("/:id/rights",
    // 参数校验中间件，用于验证角色ID参数的合法性
    function (req, res, next) {
        // 检查请求参数中的角色ID（req.params.id）是否存在，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色ID不能为空"
        if (!req.params.id) return res.sendResult(null, 400, "角色ID不能为空");
        // 验证角色ID是否可以转换为数字类型，如果不能转换成功（即不是有效的数字），则返回错误响应，状态码为400，并附带提示信息"角色ID必须为数字"
        if (isNaN(parseInt(req.params.id))) res.sendResult(null, 400, "角色ID必须为数字");
        // 参数验证通过后，将控制权传递给下一个中间件，继续后续的业务逻辑处理
        next();
    },
    // 业务逻辑中间件，用于为指定角色更新权限
    function (req, res, next) {
        // 调用roleServ角色管理模块的updateRoleRight方法，传入角色ID（req.params.id）和权限ID列表（req.body.rids），用于更新角色的权限信息，这是一个异步操作
        // 如果在更新角色权限的过程中出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
        // 如果更新成功，则返回一个空数据的响应（重点在于权限更新成功的提示），状态码为200，并附带提示信息"更新成功"
        roleServ.updateRoleRight(req.params.id, req.body.rids, function (err, newRole) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(null, 200, "更新成功");
        })(req, res, next);
    }
);

// 定义处理删除角色权限的DELETE请求的路由，路径中包含角色ID和权限ID两个参数，格式为 "/:id/rights/:rightId"
router.delete("/:id/rights/:rightId",
    // 参数验证中间件，用于验证角色ID和权限ID参数的合法性
    function (req, res, next) {
        // 检查请求参数中的角色ID（req.params.id）是否存在，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"角色ID不能为空"
        if (!req.params.id) return res.sendResult(null, 400, "角色ID不能为空");
        // 验证角色ID是否可以转换为数字类型，如果不能转换成功（即不是有效的数字），则返回错误响应，状态码为400，并附带提示信息"角色ID必须为数字"
        if (isNaN(parseInt(req.params.id))) res.sendResult(null, 400, "角色ID必须为数字");
        // 检查请求参数中的权限ID（req.params.rightId）是否存在，如果不存在则返回错误响应，状态码400表示请求参数有误，同时附带提示信息"权限ID必须为数字"
        if (isNaN(parseInt(req.params.rightId))) res.sendResult(null, 400, "权限ID必须为数字");
        // 参数验证通过后，将控制权传递给下一个中间件，继续后续的业务逻辑处理
        next();
    },
    // 业务逻辑中间件，用于执行删除指定角色的指定权限的操作
    function (req, res, next) {
        // 调用roleServ角色管理模块的deleteRoleRight方法，传入角色ID（req.params.id）和权限ID（req.params.rightId），用于删除该角色的指定权限，这是一个异步操作
        // 如果在删除角色权限的过程中出现错误（err不为null），则通过res.sendResult返回包含错误信息的响应，状态码为400，表示请求出现错误
        // 如果删除成功，则返回一个空数据的响应（重点在于提示取消权限成功），状态码为200，并附带提示信息"取消权限成功"
        roleServ.deleteRoleRight(req.params.id, req.params.rightId, function (err, result) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(result, 200, "取消权限成功");
        })(req, res, next);
    }
);

// 将配置好的路由器对象导出，以便在主应用中引入并挂载到对应的路径上，使这些路由能够正确响应客户端发送的相应HTTP请求，实现角色管理相关的各种功能
module.exports = router;