#pragma once

#include "ISTTEngine.hpp"
#include <spdlog/spdlog.h>
#include <memory>
#include <vector>
#include <string>

// PocketSphinx forward declarations (to avoid including full headers)
struct ps_decoder_s;
typedef struct ps_decoder_s ps_decoder_t;
struct cmd_ln_s;
typedef struct cmd_ln_s cmd_ln_t;

namespace celuna {

/**
 * @brief CMU PocketSphinx Speech-to-Text engine
 *
 * Lightweight keyword spotting engine ideal for passive listening.
 * Very resource-efficient, perfect for detecting wake words.
 *
 * Features:
 * - Very low CPU/memory usage
 * - Fast keyword spotting
 * - Offline (no internet required)
 * - Good for trigger words like "hey celuna"
 *
 * Limitations:
 * - Less accurate than Vosk/Whisper for full transcription
 * - Best used for keyword detection in passive mode
 */
class PocketSphinxEngine : public ISTTEngine {
public:
    /**
     * @brief Construct PocketSphinx engine
     * @param modelPath Path to PocketSphinx acoustic model directory
     * @param keywords List of keywords to detect (optional, for keyword mode)
     */
    explicit PocketSphinxEngine(const std::string& modelPath,
                                const std::vector<std::string>& keywords = {});

    ~PocketSphinxEngine() override;

    // Disable copy
    PocketSphinxEngine(const PocketSphinxEngine&) = delete;
    PocketSphinxEngine& operator=(const PocketSphinxEngine&) = delete;

    std::string transcribe(const std::vector<float>& audioData) override;
    std::string transcribeFile(const std::string& filePath) override;
    void setLanguage(const std::string& language) override;
    bool isAvailable() const override;
    std::string getEngineName() const override;

    /**
     * @brief Set keywords for detection (passive mode)
     * @param keywords List of keywords to detect
     * @param threshold Detection threshold (0.0-1.0, default 0.8)
     */
    void setKeywords(const std::vector<std::string>& keywords, float threshold = 0.8f);

private:
    bool initialize();
    void cleanup();
    std::string processAudioData(const int16_t* audioData, size_t numSamples);

    std::shared_ptr<spdlog::logger> m_logger;
    std::string m_modelPath;
    std::string m_language = "en";
    std::vector<std::string> m_keywords;
    float m_keywordThreshold = 0.8f;
    bool m_available = false;
    bool m_keywordMode = false;

    // PocketSphinx decoder (opaque pointer to avoid header dependency)
    ps_decoder_t* m_decoder = nullptr;
    cmd_ln_t* m_config = nullptr;
};

} // namespace celuna
