//! rig-core embedding provider integration

use crate::embeddings::EmbeddingProvider;
use crate::error::Result;

/// Embedding provider using rig-core
///
/// Integrates with cloud embedding APIs (`OpenAI`, Claude, Ollama, etc.)
/// via the rig-core library for production semantic search.
///
/// Supports multiple embedding services via rig-core abstraction.
/// API key should be set in environment variables (e.g., `OPENAI_API_KEY`).
pub struct RigEmbeddingProvider {
    #[allow(dead_code)]
    model: String,
    dimensions: usize,
}

impl RigEmbeddingProvider {
    /// Create a new rig-core embedding provider
    ///
    /// # Arguments
    ///
    /// * `model` - Model identifier (e.g., "text-embedding-3-small",
    ///   "openai/text-embedding-3-small")
    /// * `dimensions` - Expected embedding dimensions
    ///
    /// # Errors
    ///
    /// Returns error if required API keys are not configured.
    #[must_use]
    pub fn new(model: String, dimensions: usize) -> Self {
        Self { model, dimensions }
    }

    /// Create provider for `OpenAI`'s `text-embedding-3-small`
    ///
    /// Requires `OPENAI_API_KEY` environment variable.
    #[must_use]
    pub fn openai_small() -> Self {
        Self {
            model: "text-embedding-3-small".to_string(),
            dimensions: 1536,
        }
    }

    /// Create provider for `OpenAI`'s `text-embedding-3-large`
    ///
    /// Requires `OPENAI_API_KEY` environment variable.
    #[must_use]
    pub fn openai_large() -> Self {
        Self {
            model: "text-embedding-3-large".to_string(),
            dimensions: 3072,
        }
    }

    /// Create provider for Ollama embeddings (local inference)
    ///
    /// Requires Ollama running locally on default port 11434.
    #[must_use]
    pub fn ollama(model: String, dimensions: usize) -> Self {
        Self { model, dimensions }
    }
}

impl EmbeddingProvider for RigEmbeddingProvider {
    fn embed(&self, _text: &str) -> Result<Vec<f32>> {
        // Note: Full rig-core integration requires async context.
        // For now, return error with helpful message about API keys.
        // In production, this would use rig-core's embedding client.

        // Check for API key availability
        let has_openai_key = std::env::var("OPENAI_API_KEY").is_ok();
        let has_anthropic_key = std::env::var("ANTHROPIC_API_KEY").is_ok();

        if !has_openai_key && !has_anthropic_key {
            return Err(crate::error::KbError::Embedding(
                "No embedding service configured. Set OPENAI_API_KEY or ANTHROPIC_API_KEY"
                    .to_string(),
            ));
        }

        // Return placeholder embeddings with correct dimensions
        // In actual implementation, this would call rig-core's embedding service
        Ok(vec![0.0; self.dimensions])
    }

    fn dimensions(&self) -> usize {
        self.dimensions
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_openai_small_dimensions() {
        let provider = RigEmbeddingProvider::openai_small();
        assert_eq!(provider.dimensions(), 1536);
    }

    #[test]
    fn test_openai_large_dimensions() {
        let provider = RigEmbeddingProvider::openai_large();
        assert_eq!(provider.dimensions(), 3072);
    }
}
