#include <QApplication>
#include <QThread>

#include "dao/AccountDAO.h"
#include "views/MainWindow.h"

#include "database/DatabaseManager.h"
#include "database/dao/CommonDataDAO.h"
#include "db/AccountInfoScreener.h"
#include "services/DeviceScreener.h"
#include "automation_script/Script.h"

#include <iostream>
#include <cstdlib>
#include <thread>
#include <chrono>

#include "rshb/GetLastDaysHistoryScript.h"
#include "rshb/HomeScreenScript.h"
#include "rshb/PayByPhoneScript.h"

void setupWorkerAndThread(QCoreApplication &app) {
    auto *thread = new QThread;
    auto *deviceScreenerWorker = new DeviceScreener;

    // Перемещаем worker в новый поток thread.
    // Это значит, что все слоты worker, вызываемые через connect(), теперь будут исполняться в этом фоне-потоке.
    deviceScreenerWorker->moveToThread(thread);

    // Когда поток запустится, автоматически вызовется worker->start() внутри фонового потока.
    QObject::connect(thread, &QThread::started, deviceScreenerWorker, &DeviceScreener::start);

    // 🔁 Эти 3 строки делают автоматическую зачистку:
    // Когда worker закончит работу (emit finished()), мы:
    // - останавливаем поток (thread->quit())
    // - удаляем worker (deleteLater)
    // - удаляем thread (deleteLater)
    // Это защищает от утечек памяти и оставшихся потоков после завершения.
    QObject::connect(deviceScreenerWorker, &DeviceScreener::finished, thread, &QThread::quit);
    QObject::connect(deviceScreenerWorker, &DeviceScreener::finished, deviceScreenerWorker, &QObject::deleteLater);
    QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);

    // Когда пользователь закрывает приложение (Ctrl+C, exit() и т.п.), мы вызываем worker->stop() — ты сам пишешь, что в этом методе.
    //Обычно он просто ставит флаг m_running = false, чтобы остановить бесконечный цикл в start()
    QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
        deviceScreenerWorker->stop();
    });

    thread->start();
}

void setupWorkerAndThreadHistory(QCoreApplication &app) {
    const QString appName = "rshb";
    const QString cardNumber = "2200380317107183";
    AccountInfo account = AccountDAO::findAppAccount(appName, cardNumber);
    auto *thread = new QThread;
    auto *deviceScreenerWorker = new GetLastDaysHistoryScript(account);

    deviceScreenerWorker->moveToThread(thread);
    QObject::connect(thread, &QThread::started, deviceScreenerWorker, &GetLastDaysHistoryScript::start);
    QObject::connect(deviceScreenerWorker, &GetLastDaysHistoryScript::finished, thread, &QThread::quit);
    QObject::connect(deviceScreenerWorker, &GetLastDaysHistoryScript::finished, deviceScreenerWorker, &QObject::deleteLater);
    QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
    QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
        deviceScreenerWorker->stop();
    });

    thread->start();
}

void setupScriptAutoPaymentAndThread(QCoreApplication &app) {
    const QString appName = "rshb";
    const QString cardNumber = "2200380317107183";

    const QString phoneNumber = "79641815146";
    const QString bankName = "Альфа-Банк";
    // const QString bankName = "Сбербанк";
    const double amount = 440;

    const AccountInfo account = AccountDAO::findAppAccount(appName, cardNumber);
    if (account.id != -1) {
        // Функция для подключения потоков к завершению приложения
        auto connectStopOnQuit = [&](QObject *worker, QThread *thread) {
            QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
                if (thread->isRunning()) {
                    qDebug() << "Завершаем поток:" << thread;
                    thread->quit();
                    thread->wait(); // Ожидаем завершения потока
                }
                worker->deleteLater();
                thread->deleteLater();
            });
        };

        // Первый поток
        auto *thread = new QThread;
        auto *scriptWorker = new PayByPhoneScript(account, phoneNumber, bankName, amount);
        scriptWorker->moveToThread(thread);

        // Запуск первого потока
        QObject::connect(thread, &QThread::started, scriptWorker, &PayByPhoneScript::start);
        QObject::connect(scriptWorker, &PayByPhoneScript::finished, thread, &QThread::quit);
        QObject::connect(scriptWorker, &PayByPhoneScript::finished, scriptWorker, &QObject::deleteLater);
        QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);

        // Обработка результата первого потока
        QObject::connect(scriptWorker, &PayByPhoneScript::finishedWithResult, &app, [account, connectStopOnQuit](const QString &result) {
            qDebug() << "Получен результат: [" << result << "]";

            // Создаем второй поток после завершения первого
            auto *thread2 = new QThread;
            auto *scriptWorker2 = new GetLastDaysHistoryScript(account);
            scriptWorker2->moveToThread(thread2);

            // Запуск второго потока
            QObject::connect(thread2, &QThread::started, scriptWorker2, &GetLastDaysHistoryScript::start);
            QObject::connect(scriptWorker2, &GetLastDaysHistoryScript::finished, thread2, &QThread::quit);
            QObject::connect(scriptWorker2, &GetLastDaysHistoryScript::finished, scriptWorker2, &QObject::deleteLater);
            QObject::connect(thread2, &QThread::finished, thread2, &QThread::deleteLater);

            // Остановка второго потока при завершении приложения
            connectStopOnQuit(scriptWorker2, thread2);

            thread2->start();
        });

        // Остановка первого потока при завершении приложения
        connectStopOnQuit(scriptWorker, thread);

        // Запуск первого потока
        thread->start();
    }
}


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // QList<Card> cards = AccountInfoScreener::parseCardData(QByteArray());
    // for (const Card &card: cards) {
    //     AccountInfo info;
    //     info.deviceId = "6edc4a47";
    //     info.appName = "bank";
    //     info.cardName = card.name;
    //     info.amount = card.amount;
    //     info.description = card.description;
    //     info.status = "active";
    //     info.updateTime = QDateTime::currentDateTime();
    //     qDebug() << "Account info: " << AccountDAO::upsertAccount(info);
    // }

    setupScriptAutoPaymentAndThread(app);

    // setupWorkerAndThread(app);
    //
    // const QDateTime current = QDateTime::currentDateTimeUtc();
    // qDebug() << "Обновление lastScan:" << CommonDataDAO::updateLastScan(current);
    //
    // const QDateTime savedTime = CommonDataDAO::getLastScan();
    // qDebug() << "Сохранившееся время:" << savedTime.toString();
    //
    //
    // MainWindow window;
    // window.show();
    return app.exec();
}
