#include "houseworker.h"

#include <iostream>

HouseWorker::HouseWorker(ConnectionPool &pool, MessageBroker &broker):
    Worker(pool, broker, "HouseWorker") {

}

HouseWorker::~HouseWorker() {

}

void HouseWorker::run() {
    auto lastExecutionTime = std::chrono::steady_clock::now();
    auto lastHouseStateChange = std::chrono::system_clock::now();
    while (runningWorker) {
        signalActivity();
        auto now = std::chrono::steady_clock::now();
        auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - lastExecutionTime).count();
        if (elapsed >= 3600) {
            performTask();
        }
        auto nowSystem = std::chrono::system_clock::now();
        auto lastDay  = floor<std::chrono::days>(lastHouseStateChange);
        auto today    = floor<std::chrono::days>(nowSystem);
        if (lastDay < today) {
            performHouseStateChange();
            lastHouseStateChange = nowSystem;
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void HouseWorker::performTask() {
    try {
        setCurrentStep("Get Database Connection");
        ConnectionGuard connGuard(pool);
        auto &db = connGuard.get();
        setCurrentStep("Get new houses data");
        db.prepare("QUERY_GET_NEW_HOUSE_DATA", QUERY_GET_NEW_HOUSE_DATA);
        const auto newHouses = db.execute("QUERY_GET_NEW_HOUSE_DATA");
        for (const auto &newHouse: newHouses) {
            db.prepare("QUERY_ADD_NEW_BUYABLE_HOUSE", QUERY_ADD_NEW_BUYABLE_HOUSE);
            db.execute("QUERY_ADD_NEW_BUYABLE_HOUSE", { newHouse.at("house_id") });
        }
    } catch (const std::exception &e) {
        std::cerr << "[HouseWorker] Fehler bei der Datenbankoperation: " << e.what() << std::endl;
    }
}

void HouseWorker::performHouseStateChange() {
    try {
        ConnectionGuard connGuard(pool);
        auto &db = connGuard.get();
        // Entferne alte vorbereitete Anweisungen falls sie existieren
        try {
            db.remove("QUERY_UPDATE_BUYABLE_HOUSE_STATE");
        } catch (...) {
            // Ignoriere Fehler beim Entfernen
        }
        try {
            db.remove("QUERY_UPDATE_USER_HOUSE_STATE");
        } catch (...) {
            // Ignoriere Fehler beim Entfernen
        }
        
        // Bereite neue Anweisungen vor
        db.prepare("QUERY_UPDATE_BUYABLE_HOUSE_STATE", QUERY_UPDATE_BUYABLE_HOUSE_STATE);
        db.prepare("QUERY_UPDATE_USER_HOUSE_STATE", QUERY_UPDATE_USER_HOUSE_STATE);
        
        // Führe die Anweisungen aus
        db.execute("QUERY_UPDATE_BUYABLE_HOUSE_STATE");
        db.execute("QUERY_UPDATE_USER_HOUSE_STATE");
    } catch(const std::exception &e) {
        std::cerr << "[HouseWorker] Fehler bei der Datenbankoperation: " << e.what() << std::endl;
    }
}
