//! Comprehensive safety systems for HFT trading
//!
//! This module provides production-grade safety mechanisms to prevent
//! catastrophic financial losses in high-frequency trading systems.
//!
//! # Safety Architecture
//! - Emergency kill switches with atomic broadcasting
//! - Position limits with hybrid enforcement
//! - ML model drift detection and cutoffs
//! - Market anomaly circuit breakers
//! - Loss limits and drawdown protection
//! - Real-time risk monitoring and alerts

pub mod emergency_response;
pub mod kill_switch;
pub mod position_limiter;
pub mod safety_coordinator;
pub mod trading_gate;

// REMOVED: pub use re-export anti-pattern eliminated
// Use direct imports: use crate::safety::kill_switch::{AtomicKillSwitch, TradingGate, UnixSocketKillSwitch};
pub mod unix_socket_kill_switch;

// AGGRESSIVE FIX: RE-EXPORT ALL CONFIG TYPES TO MAKE THEM PUBLIC

// REMOVED: Direct Decimal usage - use canonical types

// Using direct types only

use std::time::Duration;
// Removed foxhunt_infrastructure - not available in this simplified risk crate

use common::types::Price;
use serde::{Deserialize, Serialize};
// CANONICAL TYPE IMPORTS - ENFORCED BY TYPE SYSTEM AGENT

/// Safety system configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `SafetyConfig` component.
pub struct SafetyConfig {
    /// Enable all safety systems
    pub enabled: bool,

    /// Kill switch configuration
    pub kill_switch: KillSwitchConfig,

    /// Position limit configuration
    pub position_limits: PositionLimiterConfig,

    /// Emergency response configuration
    pub emergency_response: EmergencyResponseConfig,

    /// Redis connection for broadcasting
    pub redis_url: String,

    /// Safety check timeout
    pub safety_check_timeout: Duration,
}

impl Default for SafetyConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            kill_switch: KillSwitchConfig::default(),
            position_limits: PositionLimiterConfig::default(),
            emergency_response: EmergencyResponseConfig::default(),
            redis_url: std::env::var("REDIS_URL").unwrap_or_else(|_| {
                let host = std::env::var("REDIS_HOST")
                    .unwrap_or_else(|_| "localhost".to_owned());
                format!("redis://{}:6379", host)
            }),
            safety_check_timeout: Duration::from_millis(10),
        }
    }
}

/// Kill switch configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `KillSwitchConfig` component.
pub struct KillSwitchConfig {
    pub enabled: bool,
    pub global_channel: String,
    pub strategy_channel_prefix: String,
    pub symbol_channel_prefix: String,
    pub auto_recovery_enabled: bool,
    pub auto_recovery_delay: Duration,
}

impl Default for KillSwitchConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            global_channel: "foxhunt:safety:kill_switch:global".to_owned(),
            strategy_channel_prefix: "foxhunt:safety:kill_switch:strategy".to_owned(),
            symbol_channel_prefix: "foxhunt:safety:kill_switch:symbol".to_owned(),
            auto_recovery_enabled: true,
            auto_recovery_delay: Duration::from_secs(300), // 5 minutes
        }
    }
}

/// Position limiter configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `PositionLimiterConfig` component.
pub struct PositionLimiterConfig {
    pub enabled: bool,
    pub cache_ttl: Duration,
    pub rpc_check_threshold_percent: f64,
    pub max_position_per_symbol: f64,
    pub max_order_value: f64,
    pub max_daily_loss: f64,
}

impl Default for PositionLimiterConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            cache_ttl: Duration::from_secs(60),
            rpc_check_threshold_percent: 0.8, // 80% of limit
            // DYNAMIC SCALING: Calculate limits based on portfolio value
            max_position_per_symbol: Self::calculate_position_limit(),
            max_order_value: Self::calculate_order_limit(),
            max_daily_loss: Self::calculate_daily_loss_limit(),
        }
    }
}

impl PositionLimiterConfig {
    /// Calculate dynamic position limit based on typical portfolio size
    /// REPLACES: hardcoded $1M limit
    fn calculate_position_limit() -> f64 {
        // Use environment variable or default to $2M portfolio assumption
        let portfolio_value = std::env::var("PORTFOLIO_VALUE")
            .unwrap_or_else(|_| "2000000.0".to_owned())
            .parse::<f64>()
            .unwrap_or(2_000_000.0);

        // 5% of portfolio value per symbol
        portfolio_value * 0.05
    }

    /// Calculate dynamic order value limit
    /// REPLACES: hardcoded $100K limit  
    fn calculate_order_limit() -> f64 {
        let portfolio_value = std::env::var("PORTFOLIO_VALUE")
            .unwrap_or_else(|_| "2000000.0".to_owned())
            .parse::<f64>()
            .unwrap_or(2_000_000.0);

        // 2% of portfolio value per order
        portfolio_value * 0.02
    }

    /// Calculate dynamic daily loss limit
    /// REPLACES: hardcoded $500K limit
    fn calculate_daily_loss_limit() -> f64 {
        let portfolio_value = std::env::var("PORTFOLIO_VALUE")
            .unwrap_or_else(|_| "2000000.0".to_owned())
            .parse::<f64>()
            .unwrap_or(2_000_000.0);

        // 10% of portfolio value daily loss limit
        portfolio_value * 0.10
    }
}

/// Emergency response configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `EmergencyResponseConfig` component.
pub struct EmergencyResponseConfig {
    pub enabled: bool,
    pub loss_check_interval: Duration,
    pub position_check_interval: Duration,
    pub max_consecutive_violations: u32,
    pub emergency_contacts: Vec<String>,
    pub max_daily_loss: Price,
    pub max_drawdown: Price,
}

impl Default for EmergencyResponseConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            loss_check_interval: Duration::from_secs(10),
            position_check_interval: Duration::from_secs(5),
            max_consecutive_violations: 5,
            emergency_contacts: vec!["risk@foxhunt.com".to_owned()],
            max_daily_loss: Price::new(1000.0).unwrap_or(Price::ZERO), // $1000.00 daily loss limit
            max_drawdown: Price::new(5000.0).unwrap_or(Price::ZERO),   // $5000.00 max drawdown
        }
    }
}
