var path = require("path");

// 获取数据库模型，通过 path.join 拼接当前工作目录和相对路径来引入模块
databaseModule = require(path.join(process.cwd(), "modules/database")); 
// 引入自定义的 logger 模块，并调用 logger 函数获取日志记录器
var logger = require('../modules/logger').logger();

/**
 * 创建对象数据
 * 
 * @param  {[type]}   modelName 模型名称，用于标识要创建数据的具体模型
 * @param  {[type]}   obj       要创建的模型对象，包含具体的数据内容
 * @param  {Function} cb        回调函数，用于处理创建操作的结果，第一个参数可能为错误信息，第二个参数为创建成功后的返回结果（如果有）
 */
module.exports.create = function (modelName, obj, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 调用模型的 create 方法创建对象，将结果传递给回调函数
    Model.create(obj, cb);
}

/**
 * 获取所有数据
 * 
 * @param  {[type]}   conditions 查询条件，用于筛选数据，包含多种可能的条件设置
 * 查询条件统一规范
 * conditions
    {
        "columns" : {
            字段条件，存储具体字段和其对应的值
            "字段名" : "条件值"
        },
        "offset" : "偏移",  // 用于分页，表示从第几条数据开始查询
        "omit" : ["字段"],  // 表示要排除的字段列表
        "only" : ["需要字段"],  // 表示只查询的字段列表
        "limit" : "",  // 表示查询的数量限制，用于分页
        "order" :[ 
            "字段", A | Z,  // 表示排序的字段和排序方向（升序或降序）
           ...
        ]
    }
 * @param  {Function} cb         回调函数，用于处理查询结果，第一个参数可能为错误信息，第二个参数为查询到的数据
 */
module.exports.list = function (modelName, conditions, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var model = db.models[modelName];
    // 如果模型不存在，调用回调函数并传递错误信息
    if (!model) return cb("模型不存在", null);
    // 根据不同的条件进行相应的查询操作
    if (conditions) {
        if (conditions["columns"]) {
            model = model.find(conditions["columns"]);
        } else {
            model = model.find();
        }
        if (conditions["offset"]) {
            model = model.offset(parseInt(conditions["offset"]));
        }
        if (conditions["limit"]) {
            model = model.limit(parseInt(conditions["limit"]));
        }
        if (conditions["only"]) {
            model = model.only(conditions["only"]);
        }
        if (conditions["omit"]) {
            model = model.omit(conditions["omit"]);
        }
        if (conditions["order"]) {
            model = model.order(conditions["order"]);
        }
    } else {
        model = model.find();
    }
    // 执行查询操作并处理结果，将结果传递给回调函数
    model.run(function (err, models) {
        if (err) {
            console.log(err);
            return cb("查询失败", null);
        }
        cb(null, models);
    });
};

module.exports.countByConditions = function (modelName, conditions, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var model = db.models[modelName];
    // 如果模型不存在，调用回调函数并传递错误信息
    if (!model) return cb("模型不存在", null);
    // 定义回调函数用于处理计数结果
    var resultCB = function (err, count) {
        if (err) {
            return cb("查询失败", null);
        }
        cb(null, count);
    }
    // 根据不同的条件进行相应的计数操作
    if (conditions) {
        if (conditions["columns"]) {
            model = model.count(conditions["columns"], resultCB);
        } else {
            model = model.count(resultCB);
        }
    } else {
        model = model.count(resultCB);
    }
};

/**
 * 获取一条数据
 * @param  {[type]}   modelName  模型名称，用于指定要查找的模型
 * @param  {[数组]}   conditions  条件集合，包含查找该条数据的具体条件
 * @param  {Function} cb         回调函数，用于处理查找结果，第一个参数可能为错误信息，第二个参数为找到的数据
 */
module.exports.findOne = function (modelName, conditions, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 如果模型不存在，调用回调函数并传递错误信息
    if (!Model) return cb("模型不存在", null);
    // 如果条件为空，调用回调函数并传递错误信息
    if (!conditions) return cb("条件为空", null);
    // 调用模型的 one 方法查找一条数据，使用日志记录器记录错误，并将结果传递给回调函数
    Model.one(conditions, function (err, obj) {
        logger.debug(err);
        if (err) {
            return cb("查询失败", null);
        }
        return cb(null, obj);
    });
}

/**
 * 更新对象数据
 * 
 * @param  {[type]}   modelName 模型名称，用于指定要更新的模型
 * @param  {[type]}   id        数据关键 ID，用于确定要更新的具体数据记录
 * @param  {[type]}   updateObj 更新对象数据，包含要更新的具体数据内容
 * @param  {Function} cb        回调函数，用于处理更新操作的结果，第一个参数可能为错误信息，第二个参数为更新成功后的返回结果（如果有）
 */
module.exports.update = function (modelName, id, updateObj, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 通过 ID 获取要更新的对象，处理获取过程中的错误，并调用对象的 save 方法更新数据
    Model.get(id, function (err, obj) {
        if (err) return cb("更新失败", null);
        obj.save(updateObj, cb);
    });
}

/**
 * 通过主键 ID 获取对象
 * @param  {[type]}   modelName 模型名称，用于指定要查找的模型
 * @param  {[type]}   id        主键 ID，用于确定要查找的具体数据记录
 * @param  {Function} cb        回调函数，用于处理查找结果，第一个参数可能为错误信息，第二个参数为找到的数据
 */
module.exports.show = function (modelName, id, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 通过 ID 获取对象，将结果传递给回调函数
    Model.get(id, function (err, obj) {
        cb(err, obj);
    });
}

/**
 * 通过主键 ID 删除对象
 * 
 * @param  {[type]}   modelName 模型名称，用于指定要删除的模型
 * @param  {[type]}   id        主键 ID，用于确定要删除的具体数据记录
 * @param  {Function} cb        回调函数，用于处理删除操作的结果，第一个参数可能为错误信息，第二个参数为删除成功后的返回结果（如果有）
 */
module.exports.destroy = function (modelName, id, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 通过 ID 获取要删除的对象，处理获取过程中的错误，并调用对象的 remove 方法删除数据
    Model.get(id, function (err, obj) {
        if (err) return cb("无模型 ID");
        obj.remove(function (err) {
            if (err) return cb("删除失败");
            return cb(null);
        });
    });
}

/**
 * 通过模型名称获取数据库数量
 * 
 * @param  {[type]}   modelName 模型名称，用于指定要统计数量的模型
 * @param  {Function} cb        回调函数，用于处理统计结果，第一个参数可能为错误信息，第二个参数为统计得到的数量
 */
module.exports.count = function (modelName, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 调用模型的 count 方法统计数量，将结果传递给回调函数
    Model.count(cb);
}

/**
 * 通过条件判断数据是否存在
 * 
 * @param  {[type]}   modelName  模块名，用于指定要检查是否存在数据的模型
 * @param  {[type]}   conditions 条件，用于判断数据是否存在的条件集合
 * @param  {Function} cb         回调函数，用于处理检查结果，第一个参数可能为错误信息，第二个参数为数据是否存在的布尔值
 */
module.exports.exists = function (modelName, conditions, cb) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    var Model = db.models[modelName];
    // 调用模型的 exists 方法检查数据是否存在，将结果传递给回调函数
    Model.exists(conditions, function (err, isExists) {
        if (err) return cb("查询失败");
        cb(null, isExists);
    });
}

module.exports.getModel = function (modelName) {
    // 从 databaseModule 中获取数据库对象
    var db = databaseModule.getDatabase();
    // 根据模型名称获取相应的模型
    return db.models[modelName];
}