#![allow(dead_code)]
#![allow(unused_imports)]
use anyhow::Result;
use std::sync::Arc;

#[derive(Clone)]
pub struct AppState {
    pub db: crate::db::MongoDb,
    pub jwt_service: crate::auth::JwtService,
    pub config: Config,
    pub audit_logger: Option<crate::security::AuditLogger>,
    pub session_manager: Option<crate::security::SessionManager>,
    pub account_lockout: Option<crate::security::AccountLockout>,
    pub health_stats_repo: Option<crate::models::health_stats::HealthStatisticsRepository>,
    pub mongo_client: Option<mongodb::Client>,

    /// Phase 2.8: Interaction checker service
    pub interaction_service: Option<Arc<crate::services::InteractionService>>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Config {
    pub server: ServerConfig,
    pub database: DatabaseConfig,
    pub jwt: JwtConfig,
    pub encryption: EncryptionConfig,
    pub cors: CorsConfig,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ServerConfig {
    pub host: String,
    pub port: u16,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DatabaseConfig {
    pub uri: String,
    pub database: String,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct JwtConfig {
    pub secret: String,
    pub access_token_expiry_minutes: i64,
    pub refresh_token_expiry_days: i64,
}

impl JwtConfig {
    pub fn access_token_expiry_duration(&self) -> std::time::Duration {
        std::time::Duration::from_secs(self.access_token_expiry_minutes as u64 * 60)
    }

    pub fn refresh_token_expiry_duration(&self) -> std::time::Duration {
        std::time::Duration::from_secs(self.refresh_token_expiry_days as u64 * 86400)
    }
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct EncryptionConfig {
    pub key: String,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CorsConfig {
    pub allowed_origins: Vec<String>,
}

impl Config {
    pub fn from_env() -> Result<Self> {
        Ok(Config {
            server: ServerConfig {
                host: std::env::var("NORMOGEN_HOST").unwrap_or_else(|_| "0.0.0.0".to_string()),
                port: std::env::var("NORMOGEN_PORT")
                    .unwrap_or_else(|_| "8080".to_string())
                    .parse()?,
            },
            database: DatabaseConfig {
                uri: std::env::var("MONGODB_URI")
                    .unwrap_or_else(|_| "mongodb://localhost:27017".to_string()),
                database: std::env::var("MONGODB_DATABASE")
                    .unwrap_or_else(|_| "normogen".to_string()),
            },
            jwt: JwtConfig {
                secret: std::env::var("JWT_SECRET").unwrap_or_else(|_| "secret".to_string()),
                access_token_expiry_minutes: std::env::var("JWT_ACCESS_TOKEN_EXPIRY_MINUTES")
                    .unwrap_or_else(|_| "15".to_string())
                    .parse()?,
                refresh_token_expiry_days: std::env::var("JWT_REFRESH_TOKEN_EXPIRY_DAYS")
                    .unwrap_or_else(|_| "7".to_string())
                    .parse()?,
            },
            encryption: EncryptionConfig {
                key: std::env::var("ENCRYPTION_KEY")
                    .unwrap_or_else(|_| "default_key_32_bytes_long!".to_string()),
            },
            cors: CorsConfig {
                allowed_origins: std::env::var("CORS_ALLOWED_ORIGINS")
                    .unwrap_or_else(|_| "http://localhost:3000".to_string())
                    .split(',')
                    .map(|s| s.to_string())
                    .collect(),
            },
        })
    }
}
