#include "DialogWeekDayDetail.h"
#include "ui_DialogWeekDayDetail.h"

#include <QDebug>
#include <QScroller>
#include <QMessageBox>
#include <QScreen>
#include <QTimer>
#include <QWindow>
#include <QDebug>
#include <QIntValidator>
#include <QPropertyAnimation>

#include "LanguageManager.h"
#include "GeneralInterface.h"

DialogWeekDayDetail::DialogWeekDayDetail(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::DialogWeekDayDetail)
{
    ui->setupUi(this);

    initWidget();
    initConnect();
}

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

void DialogWeekDayDetail::refreshData()
{
    refreshTitles(generalInfo.curDay);

    ui->tablewidget->clearContents();
    ui->tablewidget->setRowCount(0);
    foreach (const auto& data, std::as_const(m_info_list)) {
        QString limitStr;
        if (generalInfo.chargingRateUnit == ChargingProfiles::UnitType::AMPERE) {
            limitStr = QString("%1 A").arg(QString::number(data.limit));
        } else if (generalInfo.chargingRateUnit == ChargingProfiles::UnitType::WATT) {
            limitStr = QString("%1 KW").arg(QString::number(data.limit / 1000.0, 'f', 2));
        }
        QString startPeriod = GeneralInterface::getCurrentDateOfWeek(generalInfo.startTime, data.startPeriod);
        appendTableWidgetItem(startPeriod,
                              limitStr,
                              generalInfo.chargingRateUnit);
    }
}

void DialogWeekDayDetail::refreshTitles(const int &dayOfWeek)
{
    QString titles;
    switch (dayOfWeek) {
    case Qt::Monday:
        titles = "Monday limit settings";
        break;
    case Qt::Tuesday:
        titles = "Tuesday limit settings";
        break;
    case Qt::Wednesday:
        titles = "Wednesday limit settings";
        break;
    case Qt::Thursday:
        titles = "Thursday limit settings";
        break;
    case Qt::Friday:
        titles = "Friday limit settings";
        break;
    case Qt::Saturday:
        titles = "Saturday limit settings";
        break;
    case Qt::Sunday:
        titles = "Sunday limit settings";
        break;
    default:
        break;
    }

    ui->titles->setText(titles);
}

void DialogWeekDayDetail::updateData(const charging_schedule_period_info_t &info, const int &index)
{
    for(int i = 0; index < m_info_list.size(); i++) {
        if (i == index) {
            m_info_list[i] = info;
        }
    }
}

void DialogWeekDayDetail::appendTableWidgetItem(const QString &startPeriod, const QString &limit, const QString &chargingRateUnit)
{
    auto row = ui->tablewidget->rowCount();
    ui->tablewidget->insertRow(row);

    auto startTimeItem = new QTableWidgetItem(startPeriod);
    startTimeItem->setTextAlignment(Qt::AlignCenter);
    ui->tablewidget->setItem(row, 0, startTimeItem);

    auto limitTypeItem = new QTableWidgetItem(chargingRateUnit);
    limitTypeItem->setTextAlignment(Qt::AlignCenter);
    ui->tablewidget->setItem(row, 1, limitTypeItem);

    auto limitItem = new QTableWidgetItem(limit);
    limitItem->setTextAlignment(Qt::AlignCenter);
    ui->tablewidget->setItem(row, 2, limitItem);

    ui->tablewidget->setRowHeight(row, 60);
    ui->tablewidget->setCurrentItem(nullptr);
}

bool DialogWeekDayDetail::isExistByStartPeriod(const int &startPeriod)
{
    foreach (const auto& data, std::as_const(m_info_list)) {
        if (data.startPeriod == startPeriod) {
            return true;
        }
    }

    return false;
}

void DialogWeekDayDetail::centerWindow()
{
    // 确保窗口尺寸已确定（关键修复）
    this->ensurePolished();
    // this->adjustSize();

    // 获取有效的屏幕几何尺寸（考虑多显示器）
    QScreen *screen = QGuiApplication::primaryScreen();
    if (QWindow *window = this->windowHandle()) {
        screen = window->screen();
    }
    QRect screenGeometry = screen->availableGeometry();

    // 计算居中位置（考虑Wayland特性）
    int x = (screenGeometry.width() - this->width()) / 2 + screenGeometry.x();
    int y = (screenGeometry.height() - this->height()) / 2 + screenGeometry.y();

    if (QGuiApplication::platformName().contains("wayland")) {
        // Wayland专用处理
        if (QWindow *window = this->windowHandle()) {
            // 重要：延迟设置位置，确保Wayland合成器已准备好
            QTimer::singleShot(100, this, [window, x, y]() {
                window->setPosition(QPoint(x, y));

                // 替代requestActivate的方案
                window->setFlags(window->flags() | Qt::WindowStaysOnTopHint);
                QTimer::singleShot(50, [window]() {
                    window->setFlags(window->flags() & ~Qt::WindowStaysOnTopHint);
                });
            });
        }
    } else {
        // 传统X11处理
        this->move(x, y);
    }
}

void DialogWeekDayDetail::onItemDoubleClicked(QTableWidgetItem *item)
{
    auto row = item->row();
    auto data = m_info_list[row];
    Limit limit_info;
    limit_info.startPeriod      = GeneralInterface::getCurrentDateSecondOfWeek(generalInfo.startTime, data.startPeriod);
    limit_info.unit             = generalInfo.chargingRateUnit;
    limit_info.limit            = data.limit;

    m_limit_dialog->setLimit_info(limit_info);
    auto ret = m_limit_dialog->exec();
    if (ret == QDialog::Accepted) {
        auto result = m_limit_dialog->limit_info();
        data.startPeriod                = GeneralInterface::getCurrentDateOfWeek(generalInfo.startTime, result.startPeriod, generalInfo.curDay);
        generalInfo.chargingRateUnit    = result.unit;
        data.limit                      = result.limit;

        updateData(data, row);
        refreshData();
        emit valueChanged();
    }
}

void DialogWeekDayDetail::addBtnClicked()
{
    m_limit_dialog->clear();
    auto ret = m_limit_dialog->exec();
    if (ret == QDialog::Accepted) {
        auto result = m_limit_dialog->limit_info();
        if (!isExistByStartPeriod(result.startPeriod)) {
            charging_schedule_period_info_t data;
            data.startPeriod                = GeneralInterface::getCurrentDateOfWeek(generalInfo.startTime, result.startPeriod, generalInfo.curDay);
            generalInfo.chargingRateUnit    = result.unit;
            data.limit                      = result.limit;

            m_info_list.append(data);
            refreshData();
            emit valueChanged();
        } else {
            QMessageBox::warning(this, "Tips",
                                 "The time period already exists. Please add it again...");
        }
    }
}

void DialogWeekDayDetail::deleteBtnClicked()
{
    auto row = ui->tablewidget->currentRow();
    if (row > m_info_list.size()) return;
    m_info_list.removeAt(row);

    refreshData();
    emit valueChanged();
}

void DialogWeekDayDetail::showEvent(QShowEvent *event)
{
    refreshData();
    centerWindow();
    QDialog::showEvent(event);
}

QList<charging_schedule_period_info_t> DialogWeekDayDetail::info_list() const
{
    return m_info_list;
}

void DialogWeekDayDetail::setInfo_list(const QList<charging_schedule_period_info_t> &newInfo_list)
{
    m_info_list = newInfo_list;
}

GeneralInfo DialogWeekDayDetail::getGeneralInfo() const
{
    return generalInfo;
}

void DialogWeekDayDetail::setGeneralInfo(const GeneralInfo &newGeneralInfo)
{
    generalInfo = newGeneralInfo;
}

void DialogWeekDayDetail::initWidget()
{
    setWindowModality(Qt::WindowModal);
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);

    initTableWidget();
    setBackground();

    m_limit_dialog.reset(new DialogLimitEdit);
    m_limit_dialog->setParent(this);
    m_limit_dialog->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    m_limit_dialog->setWindowModality(Qt::WindowModal);
}

void DialogWeekDayDetail::setBackground()
{
    m_background = new QLabel();
    ui->background_layout->addWidget(m_background, 0, 0, ui->background_layout->rowCount(), ui->background_layout->columnCount());
    m_background->setPixmap(QPixmap(":/images/price/dialog_edit_background.png"));
    m_background->lower();
    m_background->setScaledContents(true);
}

void DialogWeekDayDetail::initTableWidget()
{
    // ui->dailyTablewidget->horizontalHeader()->hide();
    ui->tablewidget->verticalHeader()->hide();

    ui->tablewidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    ui->tablewidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tablewidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tablewidget->setSelectionMode(QAbstractItemView::SingleSelection);

    QScroller::grabGesture(ui->tablewidget,              QScroller::TouchGesture);
    QScroller::grabGesture(ui->tablewidget->viewport(),  QScroller::LeftMouseButtonGesture);
}

void DialogWeekDayDetail::initConnect()
{
    connect(ui->cancel, &QPushButton::clicked,  this, [this]() {
        reject();
    });
    connect(ui->ok, &QPushButton::clicked,      this, [this]() {
        accept();
    });
    connect(LanguageManager::instance(), &LanguageManager::languageChanged, this, [this]() {
        ui->retranslateUi(this);
    });

    connect(ui->tablewidget, &QTableWidget::itemDoubleClicked,      this, &DialogWeekDayDetail::onItemDoubleClicked);
    connect(ui->tablewidget, &QTableWidget::itemSelectionChanged,   this, [this]() {
        if (ui->tablewidget->currentItem()->row() >= 0) {
            ui->delete_limit->setVisible(true);
        } else {
            ui->delete_limit->setVisible(false);
        }
    });
    connect(ui->add_limit,      &QPushButton::clicked, this, &DialogWeekDayDetail::addBtnClicked);
    connect(ui->delete_limit,   &QPushButton::clicked, this, &DialogWeekDayDetail::deleteBtnClicked);
}
