#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "sensordialog.h"
#include "flowlayout.h"
#include "paginationbar.h"
#include "alarmwidget.h"
#include "incedentwidget.h"
#include "alarmsservice.h"
//#include "journalservice.h"

#include <QComboBox>
#include <QGridLayout>
#include <QResizeEvent>
#include <QScrollArea>
#include <QMessageBox>
#include <QTimer>
#include <QDateTime>


#include <QDebug>

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

    httpClient = new HttpClient(this);
    sensorService = new SensorService(httpClient, this);

    //sensor tab
    //какая-то лажа при запуске
    SetupSensorTab();
    startSensorTabRefreshTimer();
//------------------------------------------------------------------------------

    //loadSenorsTree(ui->treeIncidents);
    //loadSenorsTree(ui->treeJournal);

    connect(ui->treeIncidents, &QTreeWidget::itemChanged, this, &MainWindow::onTreeIncidentsChanged);
    connect(ui->treeJournal, &QTreeWidget::itemChanged, this, &MainWindow::onTreeJournalChanged);

    connect(ui->searchIncedents, &QLineEdit::textChanged, this, &MainWindow::onSearchIncedentsTextChanged);
    connect(ui->searchJournal, &QLineEdit::textChanged, this, &MainWindow::onSearchJournalTextChanged);

    ui->timeIntervalIncedents->addItems({"За всё время", "За сегодня", "За вчера", "За последние 7 дней"});
    ui->timeIntervalJournal->addItems({"За всё время", "За сегодня", "За вчера", "За последние 7 дней"});
    ui->statusJournal->addItems({"Все статусы", "Отладка", "Информация", "Предупреждение", "Ошибка", "Экстренно"});
    ui->sortJournal->addItems({"По времени", "По критичности"});


    asr = new AlarmsService(httpClient, this);
    int totalPages = asr->tmpA() / 12;
    auto *paginationBarIncidents = new PaginationBar(totalPages, this);
    QList<AlarmR> arr = asr->tmpB(1, 12);
    /*
    for(int i = 0; i < 12; ++i) {
        AlarmWidget *a = new AlarmWidget(arr[i].getSerial(), arr[i].getSensorGroup(), arr[i].getSensorId(), arr[i].getEndTime().left(10), arr[i].getEndTime().mid(11, 12), ui->scrollWidgetIncidents);
        a->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        ui->scrollLayoutIncidents->addWidget(a);
    }
    ui->paginationBarIncedentsLayout->addStretch();
    ui->paginationBarIncedentsLayout->addWidget(paginationBarIncidents);
    ui->paginationBarIncedentsLayout->addStretch();
    */

    jsr = new JournalService(httpClient, this);
    totalPages = jsr->tmpA() / 12;
    auto *paginationBarJournal = new PaginationBar(totalPages, this);
    ui->paginationBarJournalLayout->addStretch();
    ui->paginationBarJournalLayout->addWidget(paginationBarJournal);
    ui->paginationBarJournalLayout->addStretch();
    /*
    QList<LogsR> arrl = jsr->tmpB(1, 12);
    for(int i = 0; i < 12; ++i) {
        IncedentWidget *a = new IncedentWidget(arrl[i].getTime(), arrl[i].getMessage(), arrl[i].getSensorId(), arrl[i].getSensorGroup(), QString::number(arrl[i].getThreatLevel()), ui->scrollWidgetJournal);
        a->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        ui->scrollLayoutJournal->addWidget(a);
    }
    */
    connect(paginationBarIncidents, &PaginationBar::pageChanged, this, &MainWindow::onIncidentsPageChanged);
    connect(paginationBarJournal, &PaginationBar::pageChanged, this, &MainWindow::onJournalPageChanged);
}

void MainWindow::onIncidentsPageChanged(int page) {
    // Удаляем все элементы из scrollLayoutIncidents
    QLayoutItem* item;
    while ((item = ui->scrollLayoutIncidents->takeAt(0)) != nullptr) {
        if (QWidget* widget = item->widget()) {
            widget->deleteLater(); // Удаляем виджет
        }
        delete item; // Удаляем сам item
    }

    // Загружаем данные для текущей страницы
    int itemsPerPage = 12;
    QList<AlarmR> arr = asr->tmpB(page, 12);

    // Добавляем новые элементы в scrollLayoutIncidents
    for (int i = 0; i < arr.size(); ++i) {
        AlarmWidget* a = new AlarmWidget(
            arr[i].getSerial(),
            arr[i].getSensorGroup(),
            arr[i].getSensorId(),
            arr[i].getEndTime().left(10), // Дата
            arr[i].getEndTime().mid(11, 12), // Время
            ui->scrollWidgetIncidents
            );
        a->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        ui->scrollLayoutIncidents->addWidget(a);
    }
}

void MainWindow::onJournalPageChanged(int page) {
    QLayoutItem* item;
    while ((item = ui->scrollLayoutJournal->takeAt(0)) != nullptr) {
        if (QWidget* widget = item->widget()) {
            widget->deleteLater(); // Удаляем виджет
        }
        delete item; // Удаляем сам item
    }

    // Загружаем данные для текущей страницы
    int itemsPerPage = 12;
    QList<LogsR> arrl = jsr->tmpB(page, 12);

    // Добавляем новые элементы в scrollLayoutJournal
    for (int i = 0; i < arrl.size(); ++i) {
        IncedentWidget* a = new IncedentWidget(
            arrl[i].getTime(), arrl[i].getMessage(), arrl[i].getSensorId(), arrl[i].getSensorGroup(), QString::number(arrl[i].getThreatLevel()),
            ui->scrollWidgetIncidents
            );
        a->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        ui->scrollLayoutJournal->addWidget(a);
    }


}

void MainWindow::onTreeIncidentsChanged(QTreeWidgetItem *item, int column) {
    Q_UNUSED(column);

    QMap<QString, QList<int>> sensorsMap;

    if (item->parent() == nullptr) {
        // Это группа, получаем её имя
        QString groupName = item->text(0);
        QList<int> sensorIds;

        // Пройдем по дочерним элементам и добавим ID сенсоров
        for (int i = 0; i < item->childCount(); ++i) {
            QTreeWidgetItem *sensorItem = item->child(i);
            if (sensorItem->checkState(0) == Qt::Checked) {
                int sensorId = sensorItem->data(0, Qt::UserRole).toInt(); // Предполагаем, что ID сенсора сохранены в Qt::UserRole
                sensorIds.append(sensorId);
            }
        }

        // Добавляем в карту
        sensorsMap[groupName] = sensorIds;
    }
}

void MainWindow::onTreeJournalChanged(QTreeWidgetItem *item, int column) {
    Q_UNUSED(column);


    if (item->parent() == nullptr) {
        QString groupName = item->text(0);
        QList<int> sensorIds;

        for (int i = 0; i < item->childCount(); ++i) {
            QTreeWidgetItem *sensorItem = item->child(i);
            if (sensorItem->checkState(0) == Qt::Checked) {
                int sensorId = sensorItem->data(0, Qt::UserRole).toInt(); // Получаем ID сенсора
                sensorIds.append(sensorId);
            }
        }

    }
}

void MainWindow::onSearchJournalTextChanged(const QString &text) {
    Q_UNUSED(text);
    if (text.isEmpty()) {
        ui->searchJournal->setStyleSheet(R"(
            QLineEdit {
            width: 778px;
            height: 60px;
            border: 2px solid #DCD174;
            font-family: Inter;
            font-size: 26px;
            font-weight: 400;
            line-height: 31.47px;
            text-align: left;
            background: #00000000;
            color: #a6a6a6;
            }

        )");
    } else {
        ui->searchJournal->setStyleSheet(R"(
            QLineEdit {
            width: 778px;
            height: 60px;
            border: 2px solid #DCD174;
            font-family: Inter;
            font-size: 26px;
            font-weight: 400;
            line-height: 31.47px;
            text-align: left;
            background: #00000000;
            color: #13385F;
            }
        )");
    }
    //updateDisplayedWidgets();
}

void MainWindow::onSearchIncedentsTextChanged(const QString &text) {
    Q_UNUSED(text);
    if (text.isEmpty()) {
        ui->searchIncedents->setStyleSheet(R"(
            QLineEdit {
            width: 778px;
            height: 60px;
            border: 2px solid #DCD174;
            font-family: Inter;
            font-size: 26px;
            font-weight: 400;
            line-height: 31.47px;
            text-align: left;
            background: #00000000;
            color: #a6a6a6;
            }

        )");
    } else {
        ui->searchIncedents->setStyleSheet(R"(
            QLineEdit {
            width: 778px;
            height: 60px;
            border: 2px solid #DCD174;
            font-family: Inter;
            font-size: 26px;
            font-weight: 400;
            line-height: 31.47px;
            text-align: left;
            background: #00000000;
            color: #13385F;
            }
        )");
    }
    //updateDisplayedWidgets();
}

void MainWindow::loadSenorsTree(QTreeWidget* tree){
    tree->clear();

    QStringList groups = sensorService->getSensorGroups();

    for (const QString &group : groups) {
        QTreeWidgetItem *groupItem = new QTreeWidgetItem(tree);
        groupItem->setText(0, group);

        QList<Sensor> sensors = sensorService->getSensors(group);

        for (const Sensor &sensor : sensors) {
            nameToId[sensor.name] = sensor.id;
            QTreeWidgetItem *sensorItem = new QTreeWidgetItem(groupItem);
            sensorItem->setText(0, sensor.name);
            sensorItem->setCheckState(0, Qt::Checked);
        }
    }
}

void MainWindow::SetupSensorTab() {
    QScrollArea *scrollArea = new QScrollArea(this);
    scrollArea->setStyleSheet(
        "QScrollArea {"
        "    background: transparent;"
        "}"
        "QScrollBar:vertical {"
        "    background: #ebebeb;"
        "    width: 10px;"
        "    border-radius: 5px;"
        "}"
        "QScrollBar::handle:vertical {"
        "    background: #6d6d6d;"
        "    border-radius: 5px;"
        "    min-height: 20px;"
        "}"
        "QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {"
        "    border: none;"
        "    background: none;"
        "    color: none;"
        "}"
        "QScrollBar::sub-line:vertical, QScrollBar::add-line:vertical {"
        "    background: transparent;"
        "    border: none;"
        "}"
        "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {"
        "    background: transparent;"
        "}"
        );
    scrollArea->setWidgetResizable(true);
    scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    widgetContainer = new QWidget(scrollArea);
    widgetContainer->setStyleSheet("background: transparent;");
    layout = new FlowLayout(widgetContainer, 10, 10, 10);

    widgetContainer->setLayout(layout);
    scrollArea->setWidget(widgetContainer);
    ui->sensorsLayout->addWidget(scrollArea);

    connect(ui->search, &QLineEdit::textChanged, this, &MainWindow::onSearchTextChanged);
    ui->showHiddenSelect->addItems({"Да", "Нет"});
    connect(ui->groupSelect, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &MainWindow::onGroupSelected);
    connect(ui->showHiddenSelect, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &MainWindow::onShowHiddenSelected);

    loadSensorGroups();
}

void MainWindow::startSensorTabRefreshTimer() {
    QTimer *refreshTimer = new QTimer(this);

    connect(refreshTimer, &QTimer::timeout, this, [this]() {
        if (ui->tabWidget->currentWidget() == ui->sensorsTab) {
            updateDisplayedWidgets();
        }
    });

    refreshTimer->start(5000); //5 sec
}

void MainWindow::showSensorDialog(SensorWidget *sensor)
{
    SensorDialog *dialog = new SensorDialog(this, sensor, httpClient);
    dialog->setWindowModality(Qt::ApplicationModal);

    this->setStyleSheet("QMainWindow { background-color: rgba(0, 0, 0, 1); }");

    connect(dialog, &SensorDialog::resultReady, this, &MainWindow::onSensorDialogFinished);

    dialog->exec();
}

void MainWindow::onSensorDialogFinished(int result)
{
    this->setStyleSheet("");

    switch (result) {
    case SensorDialog::SaveSuccess:
        updateDisplayedWidgets();
        break;

    case SensorDialog::SaveError:
        QMessageBox::critical(nullptr, "Ошибка", "Данные не сохранены, попробуйте еще раз");
        break;

    case SensorDialog::NoSave:
        updateDisplayedWidgets();
        break;

    default:
        break;
    }
}

void MainWindow::loadSensorGroups() {
    QStringList groups = sensorService->getSensorGroups();

    if (groups.isEmpty()) {
        QTimer::singleShot(5000, this, &MainWindow::loadSensorGroups);
        return;
    }

    groups.sort(Qt::CaseInsensitive);
    ui->groupSelect->clear();
    ui->groupSelect->addItems(groups);

    if (!groups.isEmpty()) {
        loadSensors(groups.first());
    }
}

void MainWindow::loadSensors(const QString& group) {
    QList<Sensor> sensors = sensorService->getSensors(group);

    const auto &existingWidgets = widgetContainer->findChildren<SensorWidget *>();
    for (SensorWidget *widget : existingWidgets) {
        delete widget;
    }

    layout->clear();

    for (const Sensor& sensor : sensors) {
        SensorWidget* s = new SensorWidget(nullptr, sensor);
        layout->addWidget(s);

        connect(s, &SensorWidget::clicked, this, &MainWindow::showSensorDialog);
    }

    widgetContainer->update();
}

void MainWindow::updateDisplayedWidgets()
{
    QString selectedGroup = ui->groupSelect->currentText();
    QString showHidden = ui->showHiddenSelect->currentText();
    QString searchText = ui->search->text();

    // Загружаем датчики только для выбранной группы
    QList<Sensor> sensors = sensorService->getSensors(selectedGroup);

    // Храним уже добавленные виджеты
    QMap<QString, SensorWidget*> existingWidgets;

    // Сохраняем существующие виджеты и их сенсоры для последующего обновления
    const auto &widgets = widgetContainer->findChildren<SensorWidget *>();
    for (SensorWidget *widget : widgets) {
        existingWidgets[widget->getSensor().id] = widget;
    }

    layout->clear();  // Очищаем layout, но не удаляем сами виджеты

    // Проходим по новым датчикам и добавляем их в layout, если они ещё не добавлены
    for (const Sensor& sensor : sensors) {
        SensorWidget* widget = nullptr;

        // Проверяем, существует ли виджет для данного сенсора
        if (existingWidgets.contains(sensor.id)) {
            widget = existingWidgets[sensor.id];
            widget->setSensor(sensor);  // Обновляем данные существующего виджета
        } else {
            widget = new SensorWidget(nullptr, sensor);
            connect(widget, &SensorWidget::clicked, this, &MainWindow::showSensorDialog);
        }

        // Применяем фильтрацию по условиям
        bool matchesHidden = (showHidden == "Да") || !sensor.isHide;
        bool matchesSearch = sensor.name.contains(searchText, Qt::CaseInsensitive);

        if (matchesHidden && matchesSearch) {
            layout->addWidget(widget);
            widget->show();
        } else {
            widget->hide();
        }
    }

    widgetContainer->update();  // Обновляем виджеты в контейнере
}

void MainWindow::onGroupSelected(int index)
{
    Q_UNUSED(index);
    loadSensors(ui->groupSelect->currentText());
    updateDisplayedWidgets();
}

void MainWindow::onShowHiddenSelected(int index)
{
    Q_UNUSED(index);
    updateDisplayedWidgets();
}

void MainWindow::onSearchTextChanged(const QString &text)
{
    Q_UNUSED(text);
    if (text.isEmpty()) {
        ui->search->setStyleSheet(R"(
            QLineEdit {
            width: 778px;
            height: 60px;
            border: 2px solid #DCD174;
            font-family: Inter;
            font-size: 26px;
            font-weight: 400;
            line-height: 31.47px;
            text-align: left;
            background: #00000000;
            color: #a6a6a6;
            }

        )");
    } else {
        ui->search->setStyleSheet(R"(
            QLineEdit {
            width: 778px;
            height: 60px;
            border: 2px solid #DCD174;
            font-family: Inter;
            font-size: 26px;
            font-weight: 400;
            line-height: 31.47px;
            text-align: left;
            background: #00000000;
            color: #13385F;
            }
        )");
    }
    updateDisplayedWidgets();
}

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