#include "character_creation_worker.h"
#include "produce_worker.h"
#include "stockagemanager.h"
#include "director_worker.h"
#include "valuerecalculationworker.h"
#include "connection_pool.h"
#include "websocket_server.h"
#include "message_broker.h"
#include "usercharacterworker.h"
#include "houseworker.h"
#include "politics_worker.h"
#include "underground_worker.h"
#include "config.h"
#include <csignal>
#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
#include <memory>
#include <cstdlib>
#include <systemd/sd-daemon.h>

std::atomic<bool> keepRunning(true);
std::atomic<bool> shutdownRequested(false);

void handleSignal(int signal) {
    std::cerr << "Signal erhalten: " << signal << ". Beende Anwendung..." << std::endl;
    
    if (signal == SIGINT || signal == SIGTERM) {
        std::cerr << "Setze Shutdown-Flags..." << std::endl;
        keepRunning.store(false, std::memory_order_relaxed);
        shutdownRequested.store(true, std::memory_order_relaxed);
        std::cerr << "Shutdown-Flags gesetzt. keepRunning=" << keepRunning.load() << ", shutdownRequested=" << shutdownRequested.load() << std::endl;
    }
}

int main() {
    std::signal(SIGINT, handleSignal);
    std::signal(SIGTERM, handleSignal);

    try {
        Config config("/etc/yourpart/daemon.conf");
        ConnectionPool pool(
            config.get("DB_HOST"),
            config.get("DB_PORT"),
            config.get("DB_NAME"),
            config.get("DB_USER"),
            config.get("DB_PASSWORD"),
            10
        );
        int websocketPort = std::stoi(config.get("WEBSOCKET_PORT"));
        bool sslEnabled = config.get("WEBSOCKET_SSL_ENABLED") == "true";
        std::string certPath = sslEnabled ? config.get("WEBSOCKET_SSL_CERT_PATH") : "";
        std::string keyPath = sslEnabled ? config.get("WEBSOCKET_SSL_KEY_PATH") : "";
        
        MessageBroker broker;
        WebSocketServer websocketServer(websocketPort, pool, broker, sslEnabled, certPath, keyPath);
        // Use C++23 features for better performance
        std::vector<std::unique_ptr<Worker>> workers;
        workers.reserve(9); // Pre-allocate for better performance
        
        workers.emplace_back(std::make_unique<CharacterCreationWorker>(pool, broker));
        workers.emplace_back(std::make_unique<ProduceWorker>(pool, broker));
        workers.emplace_back(std::make_unique<StockageManager>(pool, broker));
        workers.emplace_back(std::make_unique<DirectorWorker>(pool, broker));
        workers.emplace_back(std::make_unique<ValueRecalculationWorker>(pool, broker));
        workers.emplace_back(std::make_unique<UserCharacterWorker>(pool, broker));
        workers.emplace_back(std::make_unique<HouseWorker>(pool, broker));
        workers.emplace_back(std::make_unique<PoliticsWorker>(pool, broker));
        workers.emplace_back(std::make_unique<UndergroundWorker>(pool, broker));
        websocketServer.setWorkers(workers);

        broker.start();
        websocketServer.run();
        for (auto &worker : workers) {
            worker->startWorkerThread();
            worker->enableWatchdog();
        }
        
        // Benachrichtige systemd, dass der Service bereit ist
        sd_notify(0, "READY=1");
        
        // Hauptschleife mit besserer Signal-Behandlung
        std::cerr << "Hauptschleife gestartet. keepRunning=" << keepRunning.load() << ", shutdownRequested=" << shutdownRequested.load() << std::endl;
        while (keepRunning.load() && !shutdownRequested.load()) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        std::cerr << "Hauptschleife beendet. keepRunning=" << keepRunning.load() << ", shutdownRequested=" << shutdownRequested.load() << std::endl;
        
        std::cerr << "Starte sauberes Herunterfahren..." << std::endl;
        
        auto shutdownStart = std::chrono::steady_clock::now();
        const auto maxShutdownTime = std::chrono::seconds(10);
        
        // Stoppe alle Worker-Threads
        std::cerr << "Stoppe Worker-Threads..." << std::endl;
        for (auto &worker : workers) {
            worker->stopWorkerThread();
            if (std::chrono::steady_clock::now() - shutdownStart > maxShutdownTime) {
                std::cerr << "Shutdown-Timeout erreicht, erzwinge Beendigung..." << std::endl;
                break;
            }
        }
        
        // Stoppe Watchdog-Threads
        std::cerr << "Stoppe Watchdog-Threads..." << std::endl;
        for (auto &worker : workers) {
            worker->stopWatchdogThread();
            if (std::chrono::steady_clock::now() - shutdownStart > maxShutdownTime) {
                std::cerr << "Shutdown-Timeout erreicht, erzwinge Beendigung..." << std::endl;
                break;
            }
        }
        
        // Stoppe WebSocket Server
        std::cerr << "Stoppe WebSocket-Server..." << std::endl;
        websocketServer.stop();
        
        // Stoppe Message Broker
        std::cerr << "Stoppe Message Broker..." << std::endl;
        broker.stop();
        
        auto shutdownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::steady_clock::now() - shutdownStart);
        std::cerr << "Anwendung erfolgreich beendet in " << shutdownDuration.count() << "ms." << std::endl;
        
        // Erzwinge sofortiges Exit nach Shutdown
        std::cerr << "Erzwinge Prozess-Beendigung..." << std::endl;
        std::_Exit(0);
    } catch (const std::exception &e) {
        std::cerr << "Fehler: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}
