#include "QWSysmgr.h"

#include "DialogPop.h"
#include "database/DAO.h"

class TableInfo;
static map<string, TableInfo> s_mapInfo;

class TableInfo
{
public:
    static void initialize()
    {
        {
            auto& info = s_mapInfo["用户管理"];
            info.addHead("user_id", "ID", 160);
            info.addHead("account", "用户名", 0);
            info.addHead("name", "姓名", 200);
            info.addHead("gender", "性别", 0);
            info.addHead("age", "年龄", 0);
            info.addHead("phone", "联系方式", 0);
            info.addHead("role_name", "角色", 200);
            info.addHead("", "操作", 0);
            info.sqlQuery = "SELECT u.*, ur.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;";
        }
        {
            auto& info = s_mapInfo["权限管理"];
            info.addHead("permission_id", "ID", 60);
            info.addHead("route", "路由", 160);
            info.addHead("name", "权限名称", 0);
            info.addHead("describe", "描述", 540);
            info.addHead("is_open", "是否启用", 0);
            info.addHead("", "操作", 0);
            info.sqlQuery = "SELECT * FROM permission;";
        }
        {
            auto& info = s_mapInfo["角色管理"];
            info.addHead("role_id", "ID", 60);
            info.addHead("name", "角色名称", 200);
            info.addHead("describe", "描述", 600);
            info.addHead("is_open", "是否启用", 0);
            info.addHead("", "操作", 0);
            info.sqlQuery = "SELECT * FROM role;";
        }
        {
            auto& info = s_mapInfo["场站管理"];
            info.addHead("station_id", "ID", 60);
            info.addHead("name", "场站名称", 160);
            info.addHead("code", "编号", 60);
            info.addHead("address", "地址", 280);
            info.addHead("lon", "经度", 0);
            info.addHead("lat", "维度", 0);
            info.addHead("attr", "参数", 200);
            info.addHead("", "操作", 0);
            info.sqlQuery = "SELECT * FROM station;";
        }
        {
            auto& info = s_mapInfo["设备管理"];
            info.addHead("device_id", "ID", 60);
            info.addHead("station_name", "所属场站", 200);
            info.addHead("type_name", "设备类型", 200);
            info.addHead("name", "设备名称", 340);
            info.addHead("code", "编号", 60);
            info.addHead("is_open", "是否启用", 0);
            info.addHead("", "操作", 0);
            info.sqlQuery = "SELECT d.*, s.name station_name, ddt.name type_name FROM"
                " device d LEFT JOIN station s ON d.station_id=s.station_id"
                " LEFT JOIN def_device_type ddt ON ddt.device_type_id = d.`type`;";
        }
        {
            auto& info = s_mapInfo["策略管理"];
            info.addHead("policy_id", "ID", 0);
            info.addHead("type_name", "策略类型", 160);
            info.addHead("name", "策略名称", 0);
            info.addHead("describe", "描述", 200);
            info.addHead("value", "参数", 400);
            info.addHead("", "操作", 0);
            info.sqlQuery = "SELECT p.*, dpt.name type_name FROM policy p LEFT JOIN def_policy_type dpt ON dpt.policy_type_id=p.`type`;";
        }
        {
            auto& info = s_mapInfo["日志管理"];
            info.addHead("", "ID", 0);
            info.addHead("", "日志类型", 0);
            info.addHead("", "内容", 0);
            info.addHead("", "状态", 0);
            info.addHead("", "操作", 0);
        }
        {
            auto& info = s_mapInfo["告警管理"];
            info.addHead("", "ID", 0);
            info.addHead("", "告警类型", 0);
            info.addHead("", "内容", 0);
            info.addHead("", "状态", 0);
            info.addHead("", "操作", 0);
        }
    };
    static TableInfo* getInfo(string name)
    {
        auto iter = s_mapInfo.find(name);
        return iter != s_mapInfo.end() ? &(iter->second) : nullptr;
    }

    struct HEAD
    {
        string key;
        string title;
        int width{ 0 };
    };

    TableInfo() {}

    void addHead(string k, string t, int w)
    {
        HEAD head;
        head.key = k;
        head.title = t;
        head.width = w;
        vecHead.push_back(head);
    }

    string name;
    string sqlQuery;
    vector<HEAD> vecHead;
};


class DialogPopUser : public DialogPop
{
public:
    DialogPopUser(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
        this->setFixedSize(500, 60 + 140 + 40 * 6);
        this->setWindowTitle(("用户管理: " + oper).c_str());
        this->addParamLine("user_id", "ID", true);
        this->addParamLine("account", "用户名");
        this->addParamLine("name", "姓名");
        this->addParamCombox("gender", "性别", { {"1", "男"}, {"0", "女"} });
        this->addParamLine("age", "年龄");
        this->addParamLine("phone", "联系方式");
    }
    void onAccept() 
    {
        if (oper == "修改")
        {
            curData.set("user_id", originData.value("user_id"));
            DAO::updateUserById(curData);
        }
    };
};

class DialogPopPermission : public DialogPop
{
public:
    DialogPopPermission(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
        this->setFixedSize(500, 60 + 140 + 40 * 5);
        this->setWindowTitle(("权限管理: " + oper).c_str());
        this->addParamLine("permission_id", "ID", true);
        this->addParamLine("route", "路由");
        this->addParamLine("name", "权限名称");
        this->addParamLine("describe", "描述");
        this->addParamCombox("is_open", "是否启用", { {"1","启用"},{"0","不启用"} });
    }
    void onAccept()
    {
        if (oper == "修改")
        {
            curData.set("permission_id", originData.value("permission_id"));
            DAO::updatePermissionById(curData);
        }
    };
};

class DialogPopRole : public DialogPop
{
public:
    DialogPopRole(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
        this->setFixedSize(500, 60 + 140 + 40 * 4);
        this->setWindowTitle(("角色管理: " + oper).c_str());
        this->addParamLine("role_id", "ID", true);
        this->addParamLine("name", "角色名称");
        this->addParamLine("describe", "描述");
        this->addParamCombox("is_open", "是否启用", { {"1","启用"},{"0","不启用"} });
    }
    void onAccept()
    {
        if (oper == "修改")
        {
            curData.set("role_id", originData.value("role_id"));
            DAO::updateRoleById(nullptr, curData);
        }
    };
};

class DialogPopStation : public DialogPop
{
public:
    DialogPopStation(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
        this->setFixedSize(500, 60 + 140 + 40 * 7);
        this->setWindowTitle(("场站管理: " + oper).c_str());
        this->addParamLine("station_id", "ID", true);
        this->addParamLine("name", "名称");
        this->addParamLine("code", "编号");
        this->addParamLine("address", "地址");
        this->addParamLine("lon", "经度");
        this->addParamLine("lat", "维度");
        this->addParamCombox("is_open", "是否启用", { {"1","启用"},{"0","不启用"} });
    }
    void onAccept()
    {
        if (oper == "修改")
        {
            curData.set("station_id", originData.value("station_id"));
            DAO::updateStationById(curData);
        }
    };
};

class DialogPopDevice : public DialogPop
{
public:
    DialogPopDevice(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
        this->setFixedSize(500, 60 + 140 + 40 * 6);
        this->setWindowTitle(("设备管理: " + oper).c_str());
        this->addParamLine("device_id", "ID", true);
        this->addParamLine("station_name", "所属场站");
        this->addParamLine("type_name", "类型");
        this->addParamLine("name", "名称");
        this->addParamLine("code", "编号");
        this->addParamCombox("is_open", "是否启用", { {"1","启用"},{"0","不启用"} });
    }   
    void onAccept()
    {
        if (oper == "修改")
        {
            curData.set("station_id", originData.value("station_id"));
            DAO::updateDeviceById(curData);
        }
    };
};
class DialogPopPolicy : public DialogPop
{
public:
    DialogPopPolicy(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
    }
};
class DialogPopLog : public DialogPop
{
public:
    DialogPopLog(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
    }
};
class DialogPopAlarm : public DialogPop
{
public:
    DialogPopAlarm(QWidget* parent, const Fields& rowdata, string oper = "") : DialogPop(parent, rowdata, oper)
    {
    }
};
QWSysmgr::QWSysmgr(QWidget* parent) : MyWidget(parent)
{
    TableInfo::initialize();

    std::vector<std::string > vecItems = {"用户管理", "权限管理", "角色管理", "场站管理", "设备管理", "策略管理", "日志管理", "告警管理"};
    vecBtnFunc.reserve(vecItems.size());
    int x = 10, y = 10;
    for (auto& itemName: vecItems)
    {
        auto btn = make_shared<QPushButton>(itemName.c_str(), this);
        btn->setObjectName(itemName);
        btn->setGeometry(x, y, 120, 36);
        btn->setStyleSheet(QSS_BTN.c_str());
        vecBtnFunc.push_back(btn);
        x += 130;
        connect(btn.get(), &QPushButton::clicked, this, &QWSysmgr::slotBtnModuleChanged);
    }

    QStringList headerTextList;
    //headerTextList << "ID" << "类型ID" << "类型名称" << "设备名称" << "编号" << "状态" << "通讯\n状态" << "工作\n状态" << "故障\n状态";

    table = MyQUI::TableWidget(this, 10, y += 100, 1350, 740);
    // 设置为水平表头
    table->setColumnCount(headerTextList.size());
    table->setHorizontalHeaderLabels(headerTextList);
    table->horizontalHeader()->setDefaultSectionSize(80);

    if (vecBtnFunc.size() > 0)
    {
        curActiveBtn = vecBtnFunc[0].get();
        curActiveBtn->setStyleSheet(QSS_BTN_ACTIVE.c_str());
        this->initTable(curActiveBtn->text().toStdString());
    }
}

QWSysmgr::~QWSysmgr()
{
}

void QWSysmgr::initTable(const string& name)
{
    QStringList headerTextList;
    auto tableInfo = TableInfo::getInfo(name);
    if (tableInfo)
    {
        for (auto& item : tableInfo->vecHead) { headerTextList << item.title.c_str(); }
    }
    table->setColumnCount(headerTextList.size());
    table->setHorizontalHeaderLabels(headerTextList);

    if (tableInfo)
    {
        for (int i = 0; i < tableInfo->vecHead.size(); ++i)
        {
            auto& item = tableInfo->vecHead[i];
            table->setColumnWidth(i, item.width > 0 ? item.width : 100);
        }
    }
    this->initTableData(name);
}

void QWSysmgr::initTableData(std::string name)
{
    table->clearContents(); // 会自动释放在setCellWidget时创建的对象
    table->setRowCount(0);

    auto tableInfo = TableInfo::getInfo(name);
    if (tableInfo)
    {
        DAO::exec(NULL, tableInfo->sqlQuery, rowFields);

        for (int row = 0; row < rowFields.size(); ++row)
        {
            auto& fields = rowFields[row];
            int col = 0;
            for (auto& item : tableInfo->vecHead)
            {
                string key = item.key;
                if (item.title == "操作")
                {
                    vector<string> items{ "修改" };
                    MyQUI::setTableCellButton(table, row, col, items, this, [=](string oper) {this->showDialogPop(name, fields, oper); });
                }
                else
                {
                    string val = fields.value(key);
                    if (key == "is_open") { val = (val == "1" ? "启用" : "未启用"); }
                    else if (key == "gender") { val = (val == "1" ? "男" : "女"); }
                    MyQUI::setTableCellText(table, row, col, val);
                }
                ++col;
            }
        }
    }
}

void QWSysmgr::showDialogPop(std::string name, const Fields& rowdata, std::string oper)
{
    shared_ptr<DialogPop> dlg;
    if (name == "用户管理") { dlg = make_shared<DialogPopUser>(this, rowdata, oper); }
    else if (name == "权限管理") { dlg = make_shared<DialogPopPermission>(this, rowdata, oper); }
    else if (name == "角色管理") { dlg = make_shared<DialogPopRole>(this, rowdata, oper); }
    else if (name == "场站管理") { dlg = make_shared<DialogPopStation>(this, rowdata, oper); }
    else if (name == "设备管理") { dlg = make_shared<DialogPopDevice>(this, rowdata, oper); }
    else if (name == "策略管理") { dlg = make_shared<DialogPopPolicy>(this, rowdata, oper); }
    else if (name == "日志管理") { dlg = make_shared<DialogPopLog>(this, rowdata, oper); }
    else if (name == "告警管理") { dlg = make_shared<DialogPopAlarm>(this, rowdata, oper); }
    if (!dlg) return;
    int ret = dlg->exec(); 
    if (ret) { this->initTableData(name); }
}

void QWSysmgr::slotBtnModuleChanged()
{    
    auto btn = dynamic_cast<QPushButton*>(sender());
    string name = btn->objectName().toStdString();
    if (btn != curActiveBtn)
    {
        if (curActiveBtn) { curActiveBtn->setStyleSheet(QSS_BTN.c_str()); }
        if (btn) { btn->setStyleSheet(QSS_BTN_ACTIVE.c_str()); }
        curActiveBtn = btn;
        this->initTable(name);
    }
}