// 导入 request 模块，该模块常用于在 Node.js 中发起 HTTP 请求，方便与其他网络服务进行交互
const request = require('request');

// 自动匹配运单号所属的物流公司
function autoComNumber(orderno) {
    // 构造请求的 URL，向快递100的接口发送请求，尝试自动匹配运单号对应的物流公司
    // 将运单号拼接到 URL 参数中，resultv2=1 可能是用于指定返回结果的某种格式或版本相关参数
    const url = `https://www.kuaidi100.com/autonumber/autoComNum?resultv2=1&text=${orderno}`;
    // 返回一个 Promise 对象，用于处理异步操作，使得外部可以使用 async/await 语法来等待该函数执行完成
    return new Promise(function (resolve, reject) {
        // 使用 request 模块发起 GET 请求，传入 URL 和回调函数，回调函数接收请求过程中的错误、响应对象以及响应体内容作为参数
        request(url, (err, response, body) => {
            // 如果请求过程中出现错误，调用 reject 函数拒绝这个 Promise，并返回包含状态码 500 和错误信息的对象
            if (err) return reject({ status: 500, msg: err.message });
            // 将响应体内容（通常是 JSON 字符串格式）解析为 JavaScript 对象，方便后续提取数据
            body = JSON.parse(body);
            // 如果解析后的 body.auto 数组长度小于等于 0，意味着没有匹配到对应的物流公司，同样调用 reject 函数拒绝 Promise，并返回相应的错误信息对象
            if (body.auto.length <= 0) return reject({ status: 501, msg: '无对应的物流公司' });
            // 如果匹配到了物流公司，调用 resolve 函数成功解决这个 Promise，返回包含状态码 200、物流公司信息以及对应的公司编码的对象
            resolve({ status: 200, msg: body.auto[0], comCode: body.auto[0].comCode });
        });
    });
}

// 定义一个异步函数，用于获取物流信息，接收 Express 框架的请求（req）和响应（res）对象作为参数（从函数名和使用方式推测可能在 Express 应用中使用）
async function getLogisticsInfo(req, res) {
    // 调用 autoComNumber 函数，传入请求参数中的运单号（req.params.orderno），并使用 await 等待该异步操作完成，获取匹配物流公司后的结果
    const result = await autoComNumber(req.params.orderno);

    // 如果返回结果的状态码不是 200，说明匹配物流公司出现问题，直接返回一个包含错误状态和相应错误消息的对象给客户端
    if (result.status!== 200) {
        return {
            meta: {
                status: 500,
                message: '获取物流信息失败！'
            }
        };
    }

    // 根据匹配到的物流公司编码和运单号构造查询物流信息的 URL，向快递100的另一个接口发送请求以获取详细物流信息
    const dataUrl = `https://www.kuaidi100.com/query?type=${result.comCode}&postid=${req.params.orderno}&temp=0.2595247267684455`;
    // 使用 request 模块发起请求，传入构造好的 URL 和回调函数，处理获取物流信息过程中的各种情况
    request(dataUrl, (err, response, body) => {
        // 如果请求过程中出现错误，使用 Express 的 res.send 方法向客户端发送包含错误状态和相应错误消息的对象，表示获取物流信息失败
        if (err) {
            return res.send({
                meta: {
                    status: 501,
                    message: '获取物流信息失败！'
                }
            });
        }
        // 如果请求成功，解析响应体内容（假设为 JSON 格式），提取其中的物流信息数据（.data 属性，具体格式取决于快递100接口返回的数据结构），
        // 然后使用 Express 的 res.send 方法向客户端发送包含成功状态、相应消息以及物流信息数据的对象，表示获取物流信息成功
        return res.send({
            meta: {
                status: 200,
                message: '获取物流信息成功！'
            },
            data: (JSON.parse(body)).data
        });
    });
}

// 将 getLogisticsInfo 函数作为模块的属性导出，方便其他模块引入并使用这个函数来获取物流信息
module.exports = {
    getLogisticsInfo
};