//这段代码整体是在处理删除分类参数相关的逻辑，先是对传入的参数（分类 ID 和参数 ID）进行严格的合
//法性验证，通过后再调用相应服务方法执行删除操作，并根据操作结果向客户端返回合适的响应信息，最
//后将路由器对象导出供外部使用。
// 引入Express框架，这是一个流行的Node.js web应用框架，用于创建服务器、处理HTTP请求以及定义路由等功能
var express = require('express');
// 创建一个Express的路由器对象，通过这个对象可以方便地定义一组相关的路由规则，用于处理不同路径和请求方法的逻辑
var router = express.Router();
// 引入Node.js的path模块，该模块提供了一系列用于处理文件路径的实用方法，比如拼接、解析路径等操作
var path = require("path");

// 获取验证模块，通过process.cwd()获取当前工作目录，然后与"/modules/authorization"路径进行拼接，
// 最终引入对应的模块。这个模块大概率用于进行权限验证相关操作，或者提供获取其他服务的入口等功能
var authorization = require(path.join(process.cwd(),"/modules/authorization"));

// 通过验证模块获取分类管理相关服务，"CategoryService"是在authorization模块内部定义好的一个服务标识，
// 借助这个标识可以调用一系列与分类管理相关的功能方法，例如获取分类列表、添加分类、删除分类等具体操作
var catServ = authorization.getService("CategoryService");

// 通过验证模块获取分类属性相关服务，同理，"AttributeService"也是在authorization模块里定义的一个服务标识，
// 专门用于处理和分类属性相关的各类操作，比如获取属性、创建属性、更新属性以及删除属性等功能
var attrServ = authorization.getService("AttributeService");

// 获取分类列表

// 引入Express框架的路由器对象（假设前面已经正确引入了Express）
// 这里重新声明了一个名为router的变量，覆盖了之前定义的router，实际使用中可能需要注意避免这种重复定义导致的混淆，
// 不过从代码逻辑看可能是想重新明确这个路由器对象用于后续路由配置，建议可以使用不同的变量名更好区分
const router = require('express').Router();

// 处理获取分类列表的GET请求，路径为根路径 "/"，意味着当客户端向服务器发送GET请求到根路径时，会进入这个路由的处理逻辑
router.get("/",
    // 第一个中间件函数，用于参数验证，在Express框架中，中间件函数是一种可以对请求进行预处理的机制，比如检查请求参数是否合法等
    function (req, res, next) {
        // 验证pagenum参数是否存在且大于0，如果不符合要求则返回错误响应，状态码400表示请求参数错误。
        // 此处代码被注释掉了，若取消注释则会进行该参数验证逻辑，即检查请求中是否传递了合法的pagenum参数，
        // 如果该参数不存在或者小于等于0，就会返回包含相应错误信息的响应给客户端
        // if (!req.query.pagenum || req.query.pagenum <= 0) return res.sendResult(null, 400, "pagenum 参数错误");
        // 验证pagesize参数是否存在且大于0，如果不符合要求则返回错误响应，
        // 此处代码被注释掉了，若取消注释则会进行该参数验证逻辑，也就是检查请求中是否传递了合法的pagesize参数，
        // 若该参数不存在或者小于等于0，同样会返回包含对应错误信息的响应给客户端
        // if (!req.query.pagesize || req.query.pagesize <= 0) return res.sendResult(null, 400, "pagesize 参数错误");
        // 如果参数验证通过，调用next()将控制权传递给下一个中间件或路由处理函数，这是Express中间件机制中用于流程控制的关键操作，
        // 保证请求能按照顺序依次经过各个中间件进行相应处理
        next();
    },
    // 第二个中间件函数，用于获取分类列表的业务逻辑处理，在前面参数验证中间件通过后，会执行这个中间件里的具体业务逻辑，即获取分类列表的操作
    function (req, res, next) {
        var conditions = null;
        // 如果pagenum和pagesize参数都存在，则构建包含这两个参数的查询条件对象，用于后续向获取分类列表的服务方法传递相应的限制条件，
        // 例如可以根据这两个参数来控制每页显示的分类数量以及获取第几页的分类数据等情况
        if (req.query.pagenum && req.query.pagesize) {
            conditions = {
                "pagenum": req.query.pagenum,
                "pagesize": req.query.pagesize
            };
        }

        // 调用catServ服务（假设是自定义的分类相关服务模块）的getAllCategories方法，传入分类类型和查询条件等参数，
        // 尝试从数据库或者其他数据存储介质中获取符合条件的分类列表信息，这是一个异步操作，通过回调函数来处理操作完成后的结果情况
        catServ.getAllCategories(req.query.type, conditions, function (err, result) {
            if (err) return res.sendResult(null, 400, "获取分类列表失败");
            res.sendResult(result, 200, "获取成功");
        })(req, res, next);
    });

// 处理创建分类的POST请求，路径为 "/"，表示当客户端向服务器的根路径发起POST请求时，会进入此路由对应的处理逻辑，
// 通常这种请求用于向服务器提交创建新分类的数据信息
router.post("/",
    // 参数验证中间件，检查请求体中是否包含cat_name字段，如果没有则返回错误响应，因为分类名称在创建分类操作中一般是必不可少的信息，
    // 所以要确保请求中包含这个字段才能进行后续的创建分类逻辑
    function (req, res, next) {
        if (!req.body.cat_name) {
            return res.sendResult(null, 400, "必须提供分类名称");
        }
        // 参数验证通过，将控制权传递给下一个中间件，继续后续创建分类的业务逻辑处理，遵循Express中间件按顺序执行的机制
        next();
    },
    // 业务逻辑中间件，用于创建分类的具体操作，在前面参数验证中间件通过后，会执行这个中间件里的实际创建分类的业务逻辑
    function (req, res, next) {
        // 调用catServ服务的addCategory方法，传入包含分类相关信息（父分类ID、分类名称、分类级别等）的对象，
        // 通过这些信息向系统中添加新的分类，将客户端提交过来的分类相关数据传递给服务层进行相应的处理，这也是一个异步操作，
        // 通过回调函数来处理操作完成后的结果情况，比如创建成功返回创建后的分类信息，失败则返回相应的错误信息
        catServ.addCategory({
            "cat_pid": req.body.cat_pid,
            "cat_name": req.body.cat_name,
            "cat_level": req.body.cat_level
        }, function (err, result) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(result, 201, "创建成功");
        })(req, res, next);
    }
);

// 处理根据分类ID获取分类详情的GET请求，路径中包含分类ID参数，如 "/:id"，这里的":id"是路由参数的占位符，
// 在实际接收到请求时，会被替换为具体的分类ID值，然后根据这个ID去获取对应的分类详情信息
router.get("/:id",
    // 参数验证中间件，检查分类ID参数是否存在以及是否为数字类型，保证获取详情的分类ID是合法有效的，
    // 因为如果分类ID不存在或者不是数字类型，后续根据这个ID去查询数据库等操作可能会出现错误情况
    function (req, res, next) {
        if (!req.params.id) {
            return res.sendResult(null, 400, "分类ID不能为空");
        }
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "分类ID必须是数字");
        // 参数验证通过，将控制权交给下一个中间件，以便继续执行获取分类详情的业务逻辑，按照Express中间件的执行顺序推进处理流程
        next();
    },
    // 正常业务逻辑中间件，用于根据分类ID获取分类详情的操作，在前面参数验证中间件通过后，会执行这个中间件里的具体获取分类详情的业务逻辑
    function (req, res, next) {
        // 调用catServ服务的getCategoryById方法，传入分类ID参数，通过该服务方法从数据存储（比如数据库）中获取对应分类的详细信息，
        // 这同样是一个异步操作，依赖回调函数来处理获取详情后的结果情况，若成功获取到详情信息则返回给客户端，失败则返回相应的错误提示
        catServ.getCategoryById(req.params.id, function (err, result) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(result, 200, "获取成功");
        })(req, res, next);
    }
);

// 处理删除分类的DELETE请求，路径中包含分类ID参数，如 "/:id"，意味着当客户端向服务器发起DELETE请求并且携带分类ID时，
// 会进入此路由对应的处理逻辑，用于执行删除指定分类的操作
router.delete("/:id",
    // 参数验证中间件，检查分类ID参数是否存在以及是否为数字类型，确保要删除的分类ID是合法有效的，
    // 避免因传入非法的分类ID导致删除操作出现意外情况，比如误删其他数据或者导致数据库报错等问题
    function (req, res, next) {
        if (!req.params.id) {
            return res.sendResult(null, 400, "分类ID不能为空");
        }
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "分类ID必须是数字");
        // 参数验证通过，将控制权交给下一个中间件，进而执行删除分类的实际业务逻辑，遵循Express中间件按顺序执行的机制
        next();
    },
    // 业务逻辑中间件，用于执行删除分类的操作，在前面参数验证中间件通过后，会执行这个中间件里的实际删除分类的业务逻辑
    function (req, res, next) {
        // 调用catServ服务的deleteCategory方法，传入分类ID参数，通过该服务方法从系统中删除指定的分类，
        // 这是一个异步操作，通过回调函数来处理删除操作完成后的情况，若成功删除分类则返回相应的提示信息，失败则返回对应的错误信息
        catServ.deleteCategory(req.params.id, function (msg) {
            res.sendResult(null, 200, msg);
        })(req, res, next);
    }
);

// 处理更新分类的PUT请求，路径中包含分类ID参数，如 "/:id"，表示当客户端向服务器发送PUT请求并携带分类ID时，
// 会进入此路由对应的处理逻辑，用于执行更新指定分类信息的操作
router.put("/:id",
    // 参数验证中间件，检查分类ID参数是否存在、是否为数字类型，以及分类名称是否为空，确保更新分类时有合法的ID以及必要的分类名称信息，
    // 因为分类名称通常是更新分类时需要修改的重要内容之一，所以要保证其存在且不为空
    function (req, res, next) {
        if (!req.params.id) {
            return res.sendResult(null, 400, "分类ID不能为空");
        }
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "分类ID必须是数字");
        if (!req.body.cat_name || req.body.cat_name == "") return res.sendResult(null, 400, "分类名称不能为空");
        // 参数验证通过，将控制权交给下一个中间件，以便继续执行更新分类的业务逻辑操作，按照Express中间件的执行顺序推进处理流程
        next();
    },
    // 业务逻辑中间件，用于执行更新分类的操作，在前面参数验证中间件通过后，会执行这个中间件里的实际更新分类信息的业务逻辑
    function (req, res, next) {
        // 调用catServ服务的updateCategory方法，传入分类ID和新的分类名称等参数，通过该服务方法对指定分类的信息进行更新，
        // 这是一个异步操作，通过回调函数来处理更新操作完成后的结果情况，若成功更新分类信息则返回更新后的分类内容，失败则返回相应的错误提示
        catServ.updateCategory(req.params.id, req.body.cat_name, function (err, result) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(result, 200, "更新成功");
        })(req, res, next);
    }
);

// 处理通过分类ID获取分类参数（attributes）的GET请求，路径为 "/:id/attributes"，用于获取指定分类下的相关属性信息，
// 根据分类ID去查找对应的属性数据
router.get("/:id/attributes",
    // 参数验证中间件，检查分类ID参数是否存在、是否为数字类型，以及属性类型（sel）是否设置正确，确保获取属性时的所有参数都是合法有效的，
    // 只有这样才能准确地从数据存储中获取到期望的属性数据，避免因参数问题导致查询出错
    function (req, res, next) {
        if (!req.params.id) {
            return res.sendResult(null, 400, "分类ID不能为空");
        }
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "分类ID必须是数字");
        if (!req.query.sel || (req.query.sel!= "only" && req.query.sel!= "many")) {
            return res.sendResult(null, 400, "属性类型必须设置");
        }
        // 参数验证通过，将控制权交给下一个中间件，继续执行获取分类参数的业务逻辑，遵循Express中间件按顺序执行的机制
        next();
    },
    // 业务逻辑中间件，用于获取分类参数的操作，在前面参数验证中间件通过后，会执行这个中间件里的具体获取分类参数的业务逻辑
    function (req, res, next) {
        // 调用attrServ服务（假设是自定义的属性相关服务模块）的getAttributes方法，传入分类ID和属性类型等参数，
        // 通过该服务方法从数据存储中获取对应分类的属性信息，这是一个异步操作，通过回调函数来处理获取属性后的结果情况，
        // 若成功获取到属性列表则返回给客户端，失败则返回相应的错误提示
        attrServ.getAttributes(req.params.id, req.query.sel, function (err, attributes) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(attributes, 200, "获取成功");
        })(req, res, next);
    }
);

// 处理根据分类ID和参数ID获取参数详情的GET请求，路径为 "/:id/attributes/:attrId"，这里的":attrId"是参数ID的路由参数占位符，
// 在实际接收到请求时，会被替换为具体的参数ID值，然后根据分类ID和参数ID去获取对应的参数详情信息
router.get("/:id/attributes/:attrId",
    // 参数验证中间件，检查分类ID和参数ID是否存在以及是否为数字类型，保证获取参数详情时的所有参数都是合法有效的，
    // 这样才能准确从数据存储中查询到对应的参数详细内容，防止因参数不合法导致查询出错
    function (req, res, next) {
        if (!req.params.id) {
            return res.sendResult(null, 400, "分类ID不能为空");
        }
        if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "分类ID必须是数字");
        if (!req.params.attrId) {
        return res.sendResult(null, 400, "参数ID不能为空");
    }
    if (isNaN(parseInt(req.params.attrId))) return res.sendResult(null, 400, "参数ID必须是数字");
    // 参数验证通过，将控制权交给下一个中间件，以便继续执行获取参数详情的业务逻辑，按照Express中间件的执行顺序推进处理流程
    next();
    },
    function (req, res, next) {
        // 调用attrServ服务的attributeById方法，传入参数ID参数，通过该服务方法从数据存储中获取对应参数的详细信息，
        // 这是一个异步操作，通过回调函数来处理获取详情后的结果情况，若成功获取到参数详情则返回给客户端，失败则返回相应的错误提示
        attrServ.attributeById(req.params.attrId, function (err, attr) {
            if (err) return res.sendResult(null, 400, err);
            res.sendResult(attr, 200, "获取成功");
        })(req, res, next);
    }
);

// 处理创建分类参数的POST请求，路径为 "/:id/attributes"，用于向指定分类下创建新的参数信息，根据分类ID来添加相应的参数数据
router.post("/:id/attributes",
    // 参数验证中间件，检查分类ID是否存在、是否为数字类型，参数名称是否为空，以及参数的attr_sel类型是否正确等，
    // 确保创建分类参数时所有传入的参数都是合法合规的，只有这样才能顺利进行后续的创建参数操作，
    // 防止因参数不符合要求导致创建失败或者出现数据异常情况
    function (req, res, next) {
        if (!req.params.id) {
            return res.sendResult(null, 400, "分类ID不能为空");
        }
       // 检查传入的 req.params.id 是否能成功转换为数字，如果不能（即不是数字格式），
// 则向客户端返回错误响应，状态码为400表示请求参数错误，同时给出相应的错误提示信息
if (isNaN(parseInt(req.params.id))) return res.sendResult(null, 400, "分类ID必须是数字");
// 检查 req.params.attrId 是否存在，如果不存在，说明参数缺失，不符合要求
if (!req.params.attrId) {
    return res.sendResult(null, 400, "参数ID不能为空");
}
// 进一步检查 req.params.attrId 是否能成功转换为数字，若不能转换，同样不符合要求，
// 要向客户端返回错误响应，告知参数格式错误
if (isNaN(parseInt(req.params.attrId))) return res.sendResult(null, 400, "参数ID必须是数字");
// 参数验证通过，调用next()函数，按照Express中间件的机制，将控制权交给下一个中间件，
// 以便继续后续的业务逻辑处理流程
next();
},
// 业务逻辑中间件，用于执行删除分类参数的操作，在前面的参数验证中间件通过后，在此执行具体的删除操作逻辑
function (req, res, next) {
    // 调用attrServ服务的deleteAttribute方法，传入参数ID参数（这里的参数ID即前面经过验证的req.params.attrId），
    // 以此来触发删除分类参数的实际操作，该操作通常是与数据库等数据存储进行交互，执行删除对应记录的动作，这是一个异步操作
    attrServ.deleteAttribute(req.params.attrId, function (err, newAttr) {
        // 如果在执行删除操作过程中出现错误（err不为null），则向客户端返回包含错误信息的响应，
        // 状态码400表示操作失败，同时将具体的错误信息传递过去
        if (err) return res.sendResult(null, 400, err);
        // 如果删除操作成功，向客户端返回成功提示信息，状态码200表示操作成功，
        // 这里返回的提示信息只是简单的"删除成功"，实际应用中可根据需求返回更详细的内容
        res.sendResult(null, 200, "删除成功");
    })(req, res, next);
});

// 将配置好的路由器对象（包含了前面定义的一系列路由及对应的处理逻辑）导出，
// 这样其他的Node.js模块就可以通过引入这个模块来使用这个路由器，
// 进而处理相应的HTTP请求，实现对应的业务功能
module.exports = router;