use std::sync::Arc;

use async_trait::async_trait;

use crate::error::Result;
use crate::types::{AudioSamples, EngineName, Transcript, TranscriptionOptions};

/// Any speech-to-text engine implements this trait.
/// Base types know nothing about their derivatives.
#[async_trait]
pub trait SpeechToText: Send + Sync {
    async fn transcribe(
        &self,
        audio: AudioSamples,
        options: &TranscriptionOptions,
    ) -> Result<Transcript>;

    fn name(&self) -> &EngineName;

    fn is_available(&self) -> bool;
}

/// Any text post-processor implements this trait.
#[async_trait]
pub trait TextProcessor: Send + Sync {
    async fn process(&self, text: &str, instruction: &str) -> Result<String>;

    fn name(&self) -> &EngineName;

    fn is_available(&self) -> bool;
}

/// Holds the active provider instances. Constructed at startup,
/// rebuilt when user changes provider in settings.
// TODO: Wire into Tauri app state once multi-engine switching is implemented.
#[allow(dead_code)]
pub struct ProviderRegistry {
    pub stt: Arc<dyn SpeechToText>,
    pub text: Option<Arc<dyn TextProcessor>>,
}
