//! Configuration WebRTC pour le stream server
//!
//! Ce module fournit la configuration WebRTC avec :
//! - Configuration des serveurs ICE (STUN/TURN)
//! - Configuration du signaling
//! - Configuration des codecs audio
//! - Gestion depuis les variables d'environnement

use serde::{Deserialize, Serialize};
use std::time::Duration;
// Note: Use tracing::info! macro directly instead of importing

use super::{AudioCodec, IceServer};

/// Configuration WebRTC pour streaming audio
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WebRTCConfig {
    pub ice_servers: Vec<IceServer>,
    pub signaling_url: String,
    pub max_peers: usize,
    pub connection_timeout: Duration,
    pub heartbeat_interval: Duration,
    pub codec_preferences: Vec<AudioCodec>,
    pub bitrate_adaptation: bool,
    pub jitter_buffer_ms: u32,
}

impl Default for WebRTCConfig {
    fn default() -> Self {
        Self {
            ice_servers: vec![IceServer {
                urls: vec!["stun:stun.l.google.com:19302".to_string()],
                username: None,
                credential: None,
            }],
            signaling_url: "ws://localhost:3002/ws/webrtc".to_string(),
            max_peers: 1000,
            connection_timeout: Duration::from_secs(30),
            heartbeat_interval: Duration::from_secs(10),
            codec_preferences: vec![
                AudioCodec::Opus { bitrate: 320 },
                AudioCodec::Aac { bitrate: 256 },
                AudioCodec::Mp3 { bitrate: 192 },
            ],
            bitrate_adaptation: true,
            jitter_buffer_ms: 100,
        }
    }
}

impl WebRTCConfig {
    /// Crée une configuration WebRTC depuis les variables d'environnement
    pub fn from_env() -> Self {
        let mut config = Self::default();

        // Configuration des serveurs ICE
        if let Ok(ice_servers) = std::env::var("WEBRTC_ICE_SERVERS") {
            config.ice_servers = Self::parse_ice_servers(&ice_servers);
            tracing::info!("🔧 WebRTC ICE servers configurés depuis WEBRTC_ICE_SERVERS");
        } else {
            // Configuration par défaut avec STUN/TURN si disponibles
            let mut ice_servers = vec![IceServer {
                urls: vec!["stun:stun.l.google.com:19302".to_string()],
                username: None,
                credential: None,
            }];

            // Ajouter serveur STUN personnalisé si configuré
            if let Ok(stun_url) = std::env::var("WEBRTC_STUN_URL") {
                ice_servers.push(IceServer {
                    urls: vec![stun_url],
                    username: None,
                    credential: None,
                });
            }

            // Ajouter serveur TURN si configuré
            if let (Ok(turn_url), Ok(turn_username), Ok(turn_credential)) = (
                std::env::var("WEBRTC_TURN_URL"),
                std::env::var("WEBRTC_TURN_USERNAME"),
                std::env::var("WEBRTC_TURN_CREDENTIAL"),
            ) {
                ice_servers.push(IceServer {
                    urls: vec![turn_url],
                    username: Some(turn_username),
                    credential: Some(turn_credential),
                });
                tracing::info!("✅ Serveur TURN configuré");
            } else {
                tracing::warn!(
                    "⚠️ Serveur TURN non configuré - certaines connexions peuvent échouer"
                );
            }

            config.ice_servers = ice_servers;
        }

        // Configuration du signaling URL
        if let Ok(signaling_url) = std::env::var("WEBRTC_SIGNALING_URL") {
            config.signaling_url = signaling_url;
            tracing::info!("🔧 WebRTC signaling URL: {}", config.signaling_url);
        } else {
            // Utiliser le port du serveur si disponible
            let port = std::env::var("STREAM_PORT")
                .or_else(|_| std::env::var("PORT"))
                .unwrap_or_else(|_| "3002".to_string());
            config.signaling_url = format!("ws://localhost:{}/ws/webrtc", port);
            tracing::info!(
                "🔧 WebRTC signaling URL par défaut: {}",
                config.signaling_url
            );
        }

        // Configuration du nombre maximum de peers
        if let Ok(max_peers) = std::env::var("WEBRTC_MAX_PEERS") {
            if let Ok(max) = max_peers.parse::<usize>() {
                config.max_peers = max;
            }
        }

        // Configuration du timeout de connexion
        if let Ok(timeout) = std::env::var("WEBRTC_CONNECTION_TIMEOUT") {
            if let Ok(secs) = timeout.parse::<u64>() {
                config.connection_timeout = Duration::from_secs(secs);
            }
        }

        // Configuration de l'intervalle de heartbeat
        if let Ok(interval) = std::env::var("WEBRTC_HEARTBEAT_INTERVAL") {
            if let Ok(secs) = interval.parse::<u64>() {
                config.heartbeat_interval = Duration::from_secs(secs);
            }
        }

        // Configuration de l'adaptation de bitrate
        if let Ok(adaptation) = std::env::var("WEBRTC_BITRATE_ADAPTATION") {
            config.bitrate_adaptation = adaptation.parse().unwrap_or(true);
        }

        // Configuration du jitter buffer
        if let Ok(jitter) = std::env::var("WEBRTC_JITTER_BUFFER_MS") {
            if let Ok(ms) = jitter.parse::<u32>() {
                config.jitter_buffer_ms = ms;
            }
        }

        tracing::info!(
            "✅ Configuration WebRTC initialisée: {} ICE servers, max_peers={}, signaling={}",
            config.ice_servers.len(),
            config.max_peers,
            config.signaling_url
        );

        config
    }

    /// Parse une chaîne de serveurs ICE au format JSON ou CSV
    ///
    /// Format JSON: `[{"urls":["stun:stun.example.com"],"username":null,"credential":null}]`
    /// Format CSV: `stun:stun.example.com,turn:turn.example.com:user:pass`
    fn parse_ice_servers(servers_str: &str) -> Vec<IceServer> {
        // Essayer de parser comme JSON d'abord
        if let Ok(servers) = serde_json::from_str::<Vec<IceServer>>(servers_str) {
            return servers;
        }

        // Sinon, parser comme CSV
        let mut servers = Vec::new();
        for server_str in servers_str.split(',') {
            let server_str = server_str.trim();
            if server_str.is_empty() {
                continue;
            }

            // Format: "turn:turn.example.com:user:pass" ou "stun:stun.example.com"
            if server_str.contains(':') {
                let parts: Vec<&str> = server_str.split(':').collect();
                if parts.len() >= 3 {
                    let protocol = parts[0];
                    let url = format!("{}:{}", protocol, parts[1]);
                    let username = if parts.len() > 3 {
                        Some(parts[2].to_string())
                    } else {
                        None
                    };
                    let credential = if parts.len() > 4 {
                        Some(parts[3].to_string())
                    } else {
                        None
                    };

                    servers.push(IceServer {
                        urls: vec![url],
                        username,
                        credential,
                    });
                } else {
                    servers.push(IceServer {
                        urls: vec![server_str.to_string()],
                        username: None,
                        credential: None,
                    });
                }
            } else {
                servers.push(IceServer {
                    urls: vec![server_str.to_string()],
                    username: None,
                    credential: None,
                });
            }
        }

        servers
    }

    /// Valide la configuration WebRTC
    pub fn validate(&self) -> Result<(), String> {
        if self.ice_servers.is_empty() {
            return Err("Au moins un serveur ICE est requis".to_string());
        }

        if self.signaling_url.is_empty() {
            return Err("URL de signaling est requise".to_string());
        }

        if !self.signaling_url.starts_with("ws://") && !self.signaling_url.starts_with("wss://") {
            return Err("URL de signaling doit être un WebSocket (ws:// ou wss://)".to_string());
        }

        if self.max_peers == 0 {
            return Err("max_peers doit être supérieur à 0".to_string());
        }

        if self.connection_timeout.as_secs() == 0 {
            return Err("connection_timeout doit être supérieur à 0".to_string());
        }

        Ok(())
    }
}

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

    #[test]
    fn test_default_config() {
        let config = WebRTCConfig::default();
        assert!(!config.ice_servers.is_empty());
        assert!(!config.signaling_url.is_empty());
        assert!(config.max_peers > 0);
        assert!(config.validate().is_ok());
    }

    #[test]
    fn test_parse_ice_servers_json() {
        let json = r#"[{"urls":["stun:stun.example.com"],"username":null,"credential":null}]"#;
        let servers = WebRTCConfig::parse_ice_servers(json);
        assert_eq!(servers.len(), 1);
        assert_eq!(servers[0].urls[0], "stun:stun.example.com");
    }

    #[test]
    fn test_parse_ice_servers_csv() {
        let csv = "stun:stun.example.com:19302,turn:turn.example.com:user:pass";
        let servers = WebRTCConfig::parse_ice_servers(csv);
        assert!(servers.len() >= 1);
    }

    #[test]
    fn test_validate_config() {
        let mut config = WebRTCConfig::default();
        assert!(config.validate().is_ok());

        config.ice_servers.clear();
        assert!(config.validate().is_err());

        config = WebRTCConfig::default();
        config.signaling_url = "".to_string();
        assert!(config.validate().is_err());

        config = WebRTCConfig::default();
        config.signaling_url = "http://example.com".to_string();
        assert!(config.validate().is_err());
    }
}
