#include "StorageModule.h"
#include <grove/JsonDataNode.h>

namespace aissia {

StorageModule::StorageModule() {
    m_logger = spdlog::get("StorageModule");
    if (!m_logger) {
        m_logger = spdlog::stdout_color_mt("StorageModule");
    }
    m_config = std::make_unique<grove::JsonDataNode>("config");
}

void StorageModule::setConfiguration(const grove::IDataNode& configNode,
                                     grove::IIO* io,
                                     grove::ITaskScheduler* scheduler) {
    m_io = io;
    m_config = std::make_unique<grove::JsonDataNode>("config");

    // Subscribe to topics
    if (m_io) {
        grove::SubscriptionConfig subConfig;
        m_io->subscribe("scheduler:task_completed", subConfig);
        m_io->subscribe("monitoring:app_changed", subConfig);
        m_io->subscribe("storage:session_saved", subConfig);
        m_io->subscribe("storage:error", subConfig);
    }

    m_logger->info("StorageModule configure (v2 - sans infrastructure)");
}

const grove::IDataNode& StorageModule::getConfiguration() {
    return *m_config;
}

void StorageModule::process(const grove::IDataNode& input) {
    processMessages();
}

void StorageModule::processMessages() {
    if (!m_io) return;

    while (m_io->hasMessages() > 0) {
        auto msg = m_io->pullMessage();

        if (msg.topic == "scheduler:task_completed" && msg.data) {
            handleTaskCompleted(*msg.data);
        }
        else if (msg.topic == "monitoring:app_changed" && msg.data) {
            handleAppChanged(*msg.data);
        }
        else if (msg.topic == "storage:session_saved" && msg.data) {
            handleSessionSaved(*msg.data);
        }
        else if (msg.topic == "storage:error" && msg.data) {
            handleStorageError(*msg.data);
        }
    }
}

void StorageModule::handleTaskCompleted(const grove::IDataNode& data) {
    std::string taskName = data.getString("taskName", "unknown");
    int duration = data.getInt("duration", 0);
    bool hyperfocus = data.getBool("hyperfocus", false);

    m_logger->debug("Task completed: {} ({}min), publishing save request", taskName, duration);

    if (m_io) {
        auto request = std::make_unique<grove::JsonDataNode>("save");
        request->setString("taskName", taskName);
        request->setInt("durationMinutes", duration);
        request->setBool("hyperfocus", hyperfocus);
        m_io->publish("storage:save_session", std::move(request));
        m_pendingSaves++;
    }
}

void StorageModule::handleAppChanged(const grove::IDataNode& data) {
    std::string appName = data.getString("oldApp", "");
    int duration = data.getInt("duration", 0);
    bool productive = data.getBool("wasProductive", false);

    if (appName.empty() || duration <= 0) return;

    m_logger->debug("App usage: {} ({}s), publishing save request", appName, duration);

    if (m_io) {
        auto request = std::make_unique<grove::JsonDataNode>("save");
        request->setInt("sessionId", m_lastSessionId);
        request->setString("appName", appName);
        request->setInt("durationSeconds", duration);
        request->setBool("productive", productive);
        m_io->publish("storage:save_app_usage", std::move(request));
        m_pendingSaves++;
    }
}

void StorageModule::handleSessionSaved(const grove::IDataNode& data) {
    m_lastSessionId = data.getInt("sessionId", 0);
    m_pendingSaves--;
    m_totalSaved++;
    m_logger->debug("Session saved: id={}", m_lastSessionId);
}

void StorageModule::handleStorageError(const grove::IDataNode& data) {
    std::string message = data.getString("message", "Unknown error");
    m_pendingSaves--;
    m_logger->error("Storage error: {}", message);
}

std::unique_ptr<grove::IDataNode> StorageModule::getHealthStatus() {
    auto status = std::make_unique<grove::JsonDataNode>("status");
    status->setString("status", "running");
    status->setInt("lastSessionId", m_lastSessionId);
    status->setInt("pendingSaves", m_pendingSaves);
    status->setInt("totalSaved", m_totalSaved);
    return status;
}

void StorageModule::shutdown() {
    m_logger->info("StorageModule arrete. Total saved: {}", m_totalSaved);
}

std::unique_ptr<grove::IDataNode> StorageModule::getState() {
    auto state = std::make_unique<grove::JsonDataNode>("state");
    state->setInt("lastSessionId", m_lastSessionId);
    state->setInt("totalSaved", m_totalSaved);
    return state;
}

void StorageModule::setState(const grove::IDataNode& state) {
    m_lastSessionId = state.getInt("lastSessionId", 0);
    m_totalSaved = state.getInt("totalSaved", 0);
    m_logger->info("Etat restore: lastSession={}, saved={}", m_lastSessionId, m_totalSaved);
}

} // namespace aissia

extern "C" {

grove::IModule* createModule() {
    return new aissia::StorageModule();
}

void destroyModule(grove::IModule* module) {
    delete module;
}

}
