#include "FormTcuSettings.h"
#include "ui_FormTcuSettings.h"

#include <QMessageBox>

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

FormTcuSettings::FormTcuSettings(BaseWidget *parent)
    : BaseWidget(parent)
    , ui(new Ui::FormTcuSettings)
{
    ui->setupUi(this);
    initComboBox();
    connectAllValueChanged(this);
    GeneralInterface::setTouchScroller(ui->scrollArea);
    connect(LanguageManager::instance(),    &LanguageManager::languageChanged,  this, [this]() { ui->retranslateUi(this); });

    connect(GLOBALS,                        &Globals::tcuConfigValueChanged,    this, [this](const TCU_CFG& info) {
        if (this->isVisible()) {
            if (isModify()) {
                auto ret = QMessageBox::information(this,
                                                    tr("tips"),
                                                    tr("Do you want to load the updated configuration file content?"),
                                                    QMessageBox::No | QMessageBox::Yes);
                if (ret == QMessageBox::Yes) {
                    // reload config file
                    m_tcu_cfg = info;
                    refreshData();
                } else if (ret == QMessageBox::No){
                    return;
                }
            } else {
                // reload config file
                m_tcu_cfg = info;
                refreshData();
            }
        }
    });
}

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

bool FormTcuSettings::returnParent()
{
    updateData();
    return ConfigManager::instance()->saveConfig(TCU_CONFIG, QVariant::fromValue(m_tcu_cfg));
}

void FormTcuSettings::initComboBox()
{
    GeneralInterface::initTimezoneComboBox(ui->timezone);
    GeneralInterface::initLanguageComboBox(ui->language);
}

void FormTcuSettings::refreshData()
{
    ui->admin_pwd->setText(m_tcu_cfg.admin_cfg.password);
    ui->operator_pwd->setText(m_tcu_cfg.operator_cfg.password);
    ui->language->setCurrentIndex(m_tcu_cfg.language);
    ui->timezone->setCurrentIndex(m_tcu_cfg.time_zone);
    ui->ccu_config_path->setText(m_tcu_cfg.ccu_config_path);
    ui->pcu_config_path->setText(m_tcu_cfg.pcu_config_path);
    ui->price_info_path->setText(m_tcu_cfg.price_info_path);
    ui->ocpp16_auth_path->setText(m_tcu_cfg.ocpp16_authorization_path);
    ui->ocpp16_charging_profiles_path->setText(m_tcu_cfg.ocpp16_charging_profile_path);
    ui->ocpp16_configkey_path->setText(m_tcu_cfg.ocpp16_config_key_path);
    ui->ocpp16_offline_charging_records_path->setText(m_tcu_cfg.ocpp16_offline_charging_records_path);
    ui->error_code_note_path->setText(m_tcu_cfg.error_code_note_path);
    ui->error_tips_visible->setChecked(m_tcu_cfg.error_tips_visible);
    ui->gun_line_temperature_visible->setChecked(m_tcu_cfg.gun_line_temperature_visible);
    ui->rs485_port_name->setText(m_tcu_cfg.rs485_port_name);
    ui->auth_type_nfc->setChecked(m_tcu_cfg.auth_type_enable.nfc);
    ui->auth_type_pos->setChecked(m_tcu_cfg.auth_type_enable.pos);
    ui->auth_type_qr->setChecked(m_tcu_cfg.auth_type_enable.qr);
    ui->tcp_recv_timeout->setValue(m_tcu_cfg.time_out.tcp_client_recv);
    ui->tcp_send_timeout->setValue(m_tcu_cfg.time_out.tcp_client_send);
    ui->tcp_heartbeat_timeout->setValue(m_tcu_cfg.time_out.tcp_heartbeat);
    ui->auth_form_wait_time->setValue(m_tcu_cfg.time_out.auth_form_wait_time);
}

void FormTcuSettings::updateData()
{
    m_tcu_cfg.admin_cfg.password                    = ui->admin_pwd->text();
    m_tcu_cfg.operator_cfg.password                 = ui->operator_pwd->text();
    m_tcu_cfg.language                              = ui->language->currentIndex();
    m_tcu_cfg.time_zone                             = ui->timezone->currentIndex();
    m_tcu_cfg.ccu_config_path                       = ui->ccu_config_path->text();
    m_tcu_cfg.pcu_config_path                       = ui->pcu_config_path->text();
    m_tcu_cfg.price_info_path                       = ui->price_info_path->text();
    m_tcu_cfg.ocpp16_authorization_path             = ui->ocpp16_auth_path->text();
    m_tcu_cfg.ocpp16_charging_profile_path          = ui->ocpp16_charging_profiles_path->text();
    m_tcu_cfg.ocpp16_config_key_path                = ui->ocpp16_configkey_path->text();
    m_tcu_cfg.ocpp16_offline_charging_records_path  = ui->ocpp16_offline_charging_records_path->text();
    m_tcu_cfg.error_code_note_path                  = ui->error_code_note_path->text();
    m_tcu_cfg.error_tips_visible                    = ui->error_tips_visible->isChecked();
    m_tcu_cfg.gun_line_temperature_visible          = ui->gun_line_temperature_visible->isVisible();
    m_tcu_cfg.rs485_port_name                       = ui->rs485_port_name->text();
    m_tcu_cfg.auth_type_enable.nfc                  = ui->auth_type_nfc->isChecked();
    m_tcu_cfg.auth_type_enable.pos                  = ui->auth_type_pos->isChecked();
    m_tcu_cfg.auth_type_enable.qr                   = ui->auth_type_qr->isChecked();
    m_tcu_cfg.time_out.tcp_client_recv              = ui->tcp_recv_timeout->value();
    m_tcu_cfg.time_out.tcp_client_send              = ui->tcp_send_timeout->value();
    m_tcu_cfg.time_out.tcp_heartbeat                = ui->tcp_heartbeat_timeout->value();
    m_tcu_cfg.time_out.auth_form_wait_time          = ui->auth_form_wait_time->value();
}

void FormTcuSettings::connectAllValueChanged(QWidget *widget)
{
    // QLineEdit
    if (auto edit = qobject_cast<QLineEdit*>(widget)) {
        connect(edit,       &QLineEdit::textChanged,                            this, &FormTcuSettings::onValueChanged);
    }
    // CustomLineEdit
    else if (auto edit = qobject_cast<CustomLineEdit*>(widget)) {
        connect(edit,       &CustomLineEdit::textChanged,                       this, &FormTcuSettings::onValueChanged);
    }
    // QSpinBox
    else if (auto spin = qobject_cast<QSpinBox*>(widget)) {
        connect(spin,       QOverload<int>::of(&QSpinBox::valueChanged),        this, &FormTcuSettings::onValueChanged);
    }
    // CustomSpinBox
    else if (auto spin = qobject_cast<CustomSpinBox*>(widget)) {
        connect(spin,       QOverload<int>::of(&CustomSpinBox::valueChanged),   this, &FormTcuSettings::onValueChanged);
    }
    // CheckBox
    else if (auto checkbox = qobject_cast<QCheckBox*>(widget)) {
        connect(checkbox,   &QCheckBox::stateChanged,                           this, &FormTcuSettings::onValueChanged);
    }

    // 递归遍历所有子控件
    auto list = widget->findChildren<QWidget*>();
    for (auto child : std::as_const(list)) {
        connectAllValueChanged(child);
    }
}

void FormTcuSettings::onValueChanged()
{
    setIsModify(true);
}

void FormTcuSettings::showEvent(QShowEvent *event)
{
    setIsModify(false);
    m_tcu_cfg = ConfigManager::instance()->tcu_cfg();
    refreshData();
    BaseWidget::showEvent(event);
}
