#pragma once

#include "IService.hpp"

#include <grove/IIO.h>
#include <grove/JsonDataNode.h>
#include <spdlog/spdlog.h>

#include <memory>
#include <string>
#include <queue>
#include <mutex>

struct sqlite3;
struct sqlite3_stmt;

namespace celuna {

/**
 * @brief Storage Service - SQLite persistence
 *
 * Handles all database operations synchronously in main thread.
 * Uses prepared statements to prevent SQL injection.
 *
 * Subscribes to:
 * - "storage:save_session"      : { taskName, durationMinutes, hyperfocus }
 * - "storage:save_app_usage"    : { sessionId, appName, durationSeconds, productive }
 * - "storage:save_conversation" : { role, content, provider, model, tokens }
 * - "storage:update_metrics"    : { focusMinutes, breaks, hyperfocusCount }
 * - "storage:query"             : { sql, params[] }
 *
 * Publishes:
 * - "storage:ready"        : Database initialized
 * - "storage:session_saved": { sessionId }
 * - "storage:error"        : { message }
 */
class StorageService : public IService {
public:
    StorageService();
    ~StorageService() override;

    bool initialize(grove::IIO* io) override;
    void process() override;
    void shutdown() override;
    std::string getName() const override { return "StorageService"; }
    bool isHealthy() const override { return m_isConnected; }

    /// Open database with config
    bool openDatabase(const std::string& dbPath,
                     const std::string& journalMode = "WAL",
                     int busyTimeoutMs = 5000);

    /// Get last inserted session ID
    int getLastSessionId() const { return m_lastSessionId; }

private:
    // Database
    sqlite3* m_db = nullptr;
    std::string m_dbPath;
    bool m_isConnected = false;
    int m_lastSessionId = 0;
    int m_totalQueries = 0;

    // Prepared statements
    sqlite3_stmt* m_stmtSaveSession = nullptr;
    sqlite3_stmt* m_stmtSaveAppUsage = nullptr;
    sqlite3_stmt* m_stmtSaveConversation = nullptr;
    sqlite3_stmt* m_stmtUpdateMetrics = nullptr;

    // Services
    grove::IIO* m_io = nullptr;
    std::shared_ptr<spdlog::logger> m_logger;

    // Database operations
    bool initializeSchema();
    bool prepareStatements();
    void finalizeStatements();

    // Message handlers
    void processMessages();
    void handleSaveSession(const grove::IDataNode& data);
    void handleSaveAppUsage(const grove::IDataNode& data);
    void handleSaveConversation(const grove::IDataNode& data);
    void handleUpdateMetrics(const grove::IDataNode& data);

    // Helpers
    bool executeSQL(const std::string& sql);
    void publishError(const std::string& message);
};

} // namespace celuna
