#include "FormSettings.h"
#include "ui_FormSettings.h"

#include "Globals.h"
#include "DataTypeDef.h"
#include "ConfigManager.h"
#include "LanguageManager.h"
#include "GeneralInterface.h"

#include "CcuSettings/FormCcuSetting.h"
#include "CcuSettings/FormOfflinePrice.h"
#include "CcuSettings/FormChargeGunType.h"
#include "CcuSettings/FormChargeGunDetail.h"
#include "CcuSettings/FormPcuhwSettings.h"
#include "CcuSettings/FormPcutcSettings.h"
#include "CcuSettings/FormQttcuSettings.h"
#include "CcuSettings/FormOcppGeneralSettings.h"

#include "TcuSettings/FormTcuSettings.h"

#include "PcuSettings/FormPcuSettings.h"

#include "OcppSettings/FormConfigurationKey.h"
#include "OcppSettings/FormLocalAuthList.h"
#include "OcppSettings/FormAuthorizationCache.h"

#include "OcppSettings/FormOcppSettings.h"
#include "OcppSettings/ChargingProfiles/FormChargingProfilesSettings.h"
#include "OcppSettings/ChargingProfiles/FormChargingPointMaxProfile.h"
#include "OcppSettings/ChargingProfiles/FormTxDufaultProfile.h"
#include "OcppSettings/ChargingProfiles/FormTxProfile.h"

#include "OtherSettings/FormOtherSettings.h"
#include "OtherSettings/FormDeviceInfo.h"
#include "OtherSettings/FormFirmwareInfo.h"
#include "OtherSettings/FormChargeRecords.h"
#include "OtherSettings/FormErrorCodeNote.h"

#include <QMessageBox>
#include <QDebug>

FormSettings::FormSettings(BaseWidget *parent)
    : BaseWidget(parent)
    , ui(new Ui::FormSettings)
{
    ui->setupUi(this);

    initWidget();
    initConnect();
    initNavigationBar();
}

FormSettings::~FormSettings()
{
    delete ui;
}

bool FormSettings::returnParent()
{
    auto form_list = m_formMap.values();
    for (QWidget* widget : std::as_const(form_list)) {
        BaseWidget* temp = qobject_cast<BaseWidget*>(widget);
        if (!temp) continue;
        if (temp->isModify()) {
            setIsModify(true);
        }
    }

    bool isSave = true;
    // if (isModify()) {
    //     auto ret = QMessageBox::question(this, tr("Save"),
    //                                      tr("The content has been modified. Do you want to save the changes?"),
    //                                      QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes);
    //     if (ret == QMessageBox::Yes) {      // save
    //         isSave = true;
    //     } else if (ret == QMessageBox::No){ // no save
    //         isSave = false;
    //     } else {                            // cancel
    //         return false;
    //     }
    // }

    for (QWidget* widget : std::as_const(form_list)) {
        BaseWidget* temp = qobject_cast<BaseWidget*>(widget);
        if (!temp) continue;
        if (temp->isModify() && isSave) {
            temp->returnParent();
        }
    }

    return true;
}

void FormSettings::initConnect()
{
    connect(LanguageManager::instance(),    &LanguageManager::languageChanged,              this,   [this]() { ui->retranslateUi(this); });
    connect(ui->navigation,                 &CustomNavigationBar::navigationItemClicked,    this,   [this](const int index){
        setPrevForm(index);
        showForm(index);
    });

    auto charging_profiles_form = qobject_cast<FormChargingProfilesSettings*>(m_formMap[Workspace::Settings::Ocpp::CHARGING_PROFILES]);
    connect(charging_profiles_form, &FormChargingProfilesSettings::currentFormChanged, this, &FormSettings::onUpdateChargingProfileData);

    connect(GLOBALS, &Globals::ccuConfigValueChanged, this, [this](const CCU_CFG& ccu_cfg) {
        if (m_ccu_cfg.GUN_Numb != ccu_cfg.GUN_Numb) {
            m_ccu_cfg = ccu_cfg;
            refreshGunSettingsNavigationBar();
        }
    });
}

void FormSettings::refreshNavigationBar()
{
    refreshGunSettingsNavigationBar();
    ui->navigation->setSelectItem(Workspace::Settings::CCU);
}

void FormSettings::refreshGunSettingsNavigationBar()
{
    auto gun_num = m_ccu_cfg.GUN_Numb;
    for(int index = 0; index < gun_num; index ++) {
        auto nodeName = QString("Gun Detail #%1").arg(index + 1);
        if (ui->navigation->findNavigationItem(nodeName)) {
            ui->navigation->removeNavigationItem(nodeName);
            m_formMap.remove(getNodeDataByGunId(index+1));
        } else {
            auto parentNodeName = QString("Charge Gun Settings");
            auto parentNode = ui->navigation->findNavigationItem(parentNodeName);
            if (parentNode) {
                ui->navigation->addNavigationItem(nodeName, getNodeDataByGunId(index+1), parentNode);
                m_formMap[getNodeDataByGunId(index+1)]    = new FormChargeGunDetail(index+1);
            }
        }
    }

    refreshStackWidget();
}

int FormSettings::getNodeDataByGunId(const int &gun_id)
{
    switch (gun_id) {
    case CHARGE_GUN_DEFAULT_1:  return Workspace::Settings::Ccu::ChargeGun::CHARGE_GUN_1;
    case CHARGE_GUN_DEFAULT_2:  return Workspace::Settings::Ccu::ChargeGun::CHARGE_GUN_2;
    default:                    return 0;
    }

    return 0;
}

void FormSettings::initNavigationBar()
{
    auto ccu = ui->navigation->addNavigationItem(tr("CCU Settings"),        Workspace::Settings::CCU);
    ui->navigation->addNavigationItem(tr("Charge Gun Settings"),            Workspace::Settings::Ccu::CHARGE_GUN,       ccu);
    ui->navigation->addNavigationItem(tr("Offline Price Settings"),         Workspace::Settings::Ccu::OFFLINE_PRICES,   ccu);
    ui->navigation->addNavigationItem(tr("pcuhw Settings"),                 Workspace::Settings::Ccu::PCUHW,            ccu);
    ui->navigation->addNavigationItem(tr("pcutc Settings"),                 Workspace::Settings::Ccu::PCUTC,            ccu);
    ui->navigation->addNavigationItem(tr("qttcu Settings"),                 Workspace::Settings::Ccu::QTTCU,            ccu);
    ui->navigation->addNavigationItem(tr("ocpp1.6 Settings"),               Workspace::Settings::Ccu::OCPP16,           ccu);
    ui->navigation->addNavigationItem(tr("ocpp2.1 Settings"),               Workspace::Settings::Ccu::OCPP21,           ccu);

    ui->navigation->addNavigationItem(tr("TCU Settings"),                   Workspace::Settings::TCU);
    ui->navigation->addNavigationItem(tr("PCU Settings"),                   Workspace::Settings::PCU);

    auto ocpp = ui->navigation->addNavigationItem(tr("OCPP Settings"),      Workspace::Settings::OCPP);
    ui->navigation->addNavigationItem(tr("Configure key"),                  Workspace::Settings::Ocpp::CONFIG_KEY,          ocpp);
    ui->navigation->addNavigationItem(tr("Local AUTH List"),                Workspace::Settings::Ocpp::LOCAL_AUTH_LIST,     ocpp);
    ui->navigation->addNavigationItem(tr("AUTH Cache"),                     Workspace::Settings::Ocpp::AUTH_CACHE,          ocpp);
    ui->navigation->addNavigationItem(tr("Charging Profiles"),              Workspace::Settings::Ocpp::CHARGING_PROFILES,   ocpp);

    auto other = ui->navigation->addNavigationItem(tr("Other Settings"),    Workspace::Settings::OTHER);
    ui->navigation->addNavigationItem(tr("device infomation"),              Workspace::Settings::Other::DEVICE_INFO,        other);
    ui->navigation->addNavigationItem(tr("Firmware infomation"),            Workspace::Settings::Other::FIRMWARE_INFO,      other);
    ui->navigation->addNavigationItem(tr("Charging Records"),               Workspace::Settings::Other::CHARGING_RECORDS,   other);
    ui->navigation->addNavigationItem(tr("Error Codes"),                    Workspace::Settings::Other::ERROR_CODE_NOTE,    other);

    ui->navigation->expandAll();
}

void FormSettings::showForm(int form)
{
    if (!m_formMap.contains(form) || !m_formMap[form]) {
        return;
    }

    setCurrentForm(form);
    ui->stackedWidget->setCurrentWidget(m_formMap[form]);

    // 更新标题栏标题
    emit refreshTitles(m_formMap[form]->windowTitle());
}

void FormSettings::onUpdateChargingProfileData(const charging_profiles_detail_info_t &info)
{
    auto index = GeneralInterface::getChargingProfilePurposeIndex(info.chargingProfilePurpose);
    switch (index) {
    case Workspace::Settings::Ocpp::ChargingProfiles::CHARGE_POINT_MAX_PROFILE:
    {
        auto maxProfileForm = qobject_cast<FormChargingPointMaxProfile*>(m_formMap[index]);
        maxProfileForm->setProfile_info(info);
        break;
    }
    case Workspace::Settings::Ocpp::ChargingProfiles::TX_DEFAULT_PROFILE:
    {
        auto txDefaultForm = qobject_cast<FormTxDufaultProfile*>(m_formMap[index]);
        txDefaultForm->setProfile_info(info);
        break;
    }
    case Workspace::Settings::Ocpp::ChargingProfiles::TX_PROFILE:
    {
        auto txForm = qobject_cast<FormTxProfile*>(m_formMap[index]);
        txForm->setProfile_info(info);
        break;
    }
    default:
        break;
    }

    setPrevForm(index);
    showForm(index);
}

void FormSettings::hideEvent(QHideEvent *event)
{
    auto form_list = m_formMap.values();
    for (QWidget* widget : std::as_const(form_list)) {
        BaseWidget* temp = qobject_cast<BaseWidget*>(widget);
        if (!temp) continue;
        temp->setIsModify(false);
    }

    setIsModify(false);
    BaseWidget::hideEvent(event);
}

void FormSettings::showEvent(QShowEvent *event)
{
    m_ccu_cfg = ConfigManager::instance()->ccu_cfg();
    refreshNavigationBar();
    BaseWidget::showEvent(event);
}

void FormSettings::slotReturnPrevForm()
{
    switch (currentForm()) {
    case Workspace::Settings::CCU:
    case Workspace::Settings::PCU:
    case Workspace::Settings::TCU:
    case Workspace::Settings::OCPP:
    case Workspace::Settings::OTHER:
        setCurrentForm(Workspace::Home::SETTINGS);
        emit returnPrevForm();
        break;
    case Workspace::Settings::Ccu::ChargeGun::CHARGE_GUN_1:
    case Workspace::Settings::Ccu::ChargeGun::CHARGE_GUN_2:
        showForm(Workspace::Settings::Ccu::CHARGE_GUN);
        ui->navigation->setSelectItem(Workspace::Settings::Ccu::CHARGE_GUN);
        break;
    case Workspace::Settings::Ccu::CHARGE_GUN:
    case Workspace::Settings::Ccu::OFFLINE_PRICES:
    case Workspace::Settings::Ccu::PCUHW:
    case Workspace::Settings::Ccu::PCUTC:
    case Workspace::Settings::Ccu::QTTCU:
    case Workspace::Settings::Ccu::OCPP16:
    case Workspace::Settings::Ccu::OCPP21:
        showForm(Workspace::Settings::CCU);
        ui->navigation->setSelectItem(Workspace::Settings::CCU);
        break;
    case Workspace::Settings::Ocpp::CONFIG_KEY:
    case Workspace::Settings::Ocpp::LOCAL_AUTH_LIST:
    case Workspace::Settings::Ocpp::AUTH_CACHE:
    case Workspace::Settings::Ocpp::CHARGING_PROFILES:
        showForm(Workspace::Settings::OCPP);
        ui->navigation->setSelectItem(Workspace::Settings::OCPP);
        break;
    case Workspace::Settings::Ocpp::ChargingProfiles::TX_PROFILE:
    case Workspace::Settings::Ocpp::ChargingProfiles::TX_DEFAULT_PROFILE:
    case Workspace::Settings::Ocpp::ChargingProfiles::CHARGE_POINT_MAX_PROFILE:
        showForm(Workspace::Settings::Ocpp::CHARGING_PROFILES);
        ui->navigation->setSelectItem(Workspace::Settings::Ocpp::CHARGING_PROFILES);
        break;
    case Workspace::Settings::Other::DEVICE_INFO:
    case Workspace::Settings::Other::FIRMWARE_INFO:
    case Workspace::Settings::Other::CHARGING_RECORDS:
    case Workspace::Settings::Other::ERROR_CODE_NOTE:
        showForm(Workspace::Settings::OTHER);
        ui->navigation->setSelectItem(Workspace::Settings::OTHER);
        break;
    default:
        break;
    }
}

void FormSettings::initWidget()
{
    setCurrentForm(Workspace::Home::SETTINGS);
    setPrevForm(Workspace::Home::SETTINGS);
    ui->old_settings->setWindowTitle(tr("Settings"));
    ui->new_settings->setWindowTitle(tr("Settings"));

    m_formMap[Workspace::Settings::CCU]                                                 = new FormCcuSetting();
    m_formMap[Workspace::Settings::Ccu::OFFLINE_PRICES]                                 = new FormOfflinePrice();
    m_formMap[Workspace::Settings::Ccu::CHARGE_GUN]                                     = new FormChargeGunType();
    m_formMap[Workspace::Settings::Ccu::PCUHW]                                          = new FormPcuhwSettings();
    m_formMap[Workspace::Settings::Ccu::PCUTC]                                          = new FormPcutcSettings();
    m_formMap[Workspace::Settings::Ccu::QTTCU]                                          = new FormQttcuSettings();
    m_formMap[Workspace::Settings::Ccu::OCPP16]                                         = new FormOcppGeneralSettings(OcppVersion::OCPP16);
    m_formMap[Workspace::Settings::Ccu::OCPP21]                                         = new FormOcppGeneralSettings(OcppVersion::OCPP21);

    m_formMap[Workspace::Settings::TCU]                                                 = new FormTcuSettings();
    m_formMap[Workspace::Settings::PCU]                                                 = new FormPcuSettings();

    m_formMap[Workspace::Settings::OCPP]                                                = new FormOcppSettings();
    m_formMap[Workspace::Settings::Ocpp::CONFIG_KEY]                                    = new FormConfigurationKey();
    m_formMap[Workspace::Settings::Ocpp::LOCAL_AUTH_LIST]                               = new FormLocalAuthList();
    m_formMap[Workspace::Settings::Ocpp::AUTH_CACHE]                                    = new FormAuthorizationCache();
    m_formMap[Workspace::Settings::Ocpp::CHARGING_PROFILES]                             = new FormChargingProfilesSettings();

    m_formMap[Workspace::Settings::Ocpp::ChargingProfiles::CHARGE_POINT_MAX_PROFILE]    = new FormChargingPointMaxProfile();
    m_formMap[Workspace::Settings::Ocpp::ChargingProfiles::TX_DEFAULT_PROFILE]          = new FormTxDufaultProfile();
    m_formMap[Workspace::Settings::Ocpp::ChargingProfiles::TX_PROFILE]                  = new FormTxProfile();

    m_formMap[Workspace::Settings::OTHER]                                               = new FormOtherSettings();
    m_formMap[Workspace::Settings::Other::DEVICE_INFO]                                  = new FormDeviceInfo();
    m_formMap[Workspace::Settings::Other::FIRMWARE_INFO]                                = new FormFirmwareInfo();
    m_formMap[Workspace::Settings::Other::CHARGING_RECORDS]                             = new FormChargeRecords();
    m_formMap[Workspace::Settings::Other::ERROR_CODE_NOTE]                              = new FormErrorCodeNote();

    refreshStackWidget();
}

void FormSettings::refreshStackWidget()
{
    // 添加页面到堆叠窗口并隐藏
    auto widgets = m_formMap.values();
    foreach (const auto& widget, std::as_const(widgets)) {
        ui->stackedWidget->addWidget(widget);

        // 强制布局系统更新
        ui->stackedWidget->updateGeometry();
    }

    // 显示初始页面
    showForm(Workspace::Home::SETTINGS);
}
