#include "Dao1.h"
#include "common/Logger.h"
#include "common/Utils.h"
#include "common/Snowflake.h"



enum class EnDatabaseErr
{
    SUCCESS = 0,
};

std::shared_ptr<DaoEntity> DAO1::get(std::string tableName)
{
    return std::make_shared<DaoEntity>(tableName);
}

Errcode DAO1::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, Fields& fields)
{
    std::string err;
    std::string t = Utils::timeStr();
    if (!dao)
    {
        dao = std::make_shared<DaoEntity>("");
    }
    if (!dao->isConnected())
    {
        err = "数据库连接错误";
        DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
        return Errcode::ERR_DB_CONN;
    }

    std::string sql =  "SELECT u.*, ur.role_id  FROM `user` u"
        " LEFT JOIN user_role ur ON u.user_id = ur.user_id WHERE u.account=" + account + "';";

    std::vector<Fields> result;
    bool ret = dao->exec(sql, result);
    if (!ret)
    {
        err = "数据库操作错误";
        DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
        return Errcode::ERR_DB_CONN;
    }
    if (result.size() <=0)
    {
        err = "用户不存在";
        DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
        return Errcode::ERR_LOGIN_USER_NOTEXIST;
    }
    fields = result[0];
    std::string userId = fields.value("user_id");
    int loginCount = fields.get<int>("login_count");

    // 判断密码
    if (passwd != fields.value("passwd"))
    {
        err = "密码错误";
        DAO1::writeSystemLog(dao, 2, userId, account, "用户登录失败:" + err);
        return Errcode::ERR_LOGIN_PASSWD;
    }

    // 读取用户权限
    {
        result.clear();
        std::string sql = "SELECT rp.role_id, rp.permission_id, p.name FROM role_permission rp "
            "LEFT JOIN permission p ON p.permission_id = rp.permission_id"
            "WHERE rp.role_id = 1;";

    }

    err = "登录成功";

    // 数据库更新用户登录信息
    sql = "UPDATE user SET login_time='" + t + "', login_count='" + std::to_string(loginCount + 1) + "' WHERE user_id = '" +  userId + "'; ";
    ret = dao->exec(sql);
    if (!ret)
    {
        XLOGE() << "更新用户登录信息失败：sql=" << sql;
    }

    DAO1::writeSystemLog(dao, 2, userId, account, "用户登录成功");
    return Errcode::OK;
}

bool DAO1::writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text)
{
    if (!dao)
    {
        dao = std::make_shared<DaoEntity>("");
    }
    if (!dao->isConnected())
    {
        return false;
    }

    // 数据库写入登录日志
    dao->setTableName("system_log");
    Fields fieldsLog;
    fieldsLog.set("log_id", Snowflake::instance().getIdStr());
    fieldsLog.set("type", 2);
    fieldsLog.set("user_id", userId);
    fieldsLog.set("user_account", account);
    fieldsLog.set("content", text);
    fieldsLog.set("create_time", Utils::timeStr());
    bool ret = dao->insertFields({fieldsLog});
    return ret;
}


bool DAO1::queryUser(std::vector<Fields>& res)
{
    std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>("");
    if (!dao->isConnected())
    {
        return false;
    }
    std::string sql = "SELECT u.*, r.role_id, r.name role_name from USER u LEFT JOIN user_role ur ON u.user_id = ur.user_id LEFT JOIN `role` r ON r.role_id = ur.role_id;";
    bool ret = dao->exec(sql, res);
    return ret;
}

int DAO1::insertUser(Fields& fields)
{
    std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>("user");
    if (!dao->isConnected())
    {
        return 1;
    }

    std::string account = fields.value("account");

    // step1: 查询
    std::vector<Fields> res;
    bool ret = dao->exec("SELECT * from user WHERE account='" + account + "';", res);
    if (!ret)
    {
        return 1;
    }
    if (res.size() > 0)
    {
        return 1;
    }

    fields.set("user_id", Snowflake::instance().getIdStr());
    fields.set("create_time", Utils::timeStr());
    ret = dao->insertFields(fields);
    return (ret) ? 0 : 1;
}

int DAO1::updateUserById(std::string id, Fields& fields)
{
    std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>("user");
    if (!dao->isConnected())
    {
        return 1;
    }
    string sqlC = "WHERE user_id='" + id + "'";
    bool ret = dao->updateFields(fields, sqlC);
    return (ret) ? 0 : 1;
}