//! Dynamic Model Weight Management for Ensemble Learning
//!
//! Implements sophisticated weight adjustment algorithms with performance-based
//! adaptation, regime detection, and memory-efficient storage for HFT applications.

use std::collections::HashMap;

// CIRCULAR DEPENDENCY FIX: Use MarketRegime from core types

use crate::MLError;

#[derive(Debug, Clone)]
pub enum WeightUpdateMethod {
    PerformanceBased,
    EqualWeight,
    AdaptiveDecay,
    RegimeBased,
}

#[derive(Debug)]
pub struct ModelWeights {
    weights: HashMap<String, f64>,
    update_method: WeightUpdateMethod,
}

impl ModelWeights {
    pub fn new(update_method: WeightUpdateMethod) -> Self {
        Self {
            weights: HashMap::new(),
            update_method,
        }
    }

    pub fn add_model(&mut self, model_id: &str, weight: f64) {
        self.weights.insert(model_id.to_string(), weight);
    }

    pub fn initialize_equal_weights(&self, _model_ids: &[String]) {
        // Implementation for equal weights initialization
    }
}

#[derive(Debug)]
#[derive(Default)]
pub struct WeightConfig {
    pub regime_adaptation: bool,
}


#[derive(Debug)]
pub struct DynamicWeightManager {
    config: WeightConfig,
    models: HashMap<String, String>,
}

impl DynamicWeightManager {
    pub fn new(config: WeightConfig) -> Self {
        Self {
            config,
            models: HashMap::new(),
        }
    }

    pub fn register_model(&self, _id: &str, _model_type: &str) -> Result<(), MLError> {
        // Implementation for model registration
        Ok(())
    }

    pub fn update_model_performance(
        &self,
        _id: &str,
        _accuracy: f64,
        _pnl: f64,
    ) -> Result<(), MLError> {
        // Implementation for performance update
        Ok(())
    }

    pub fn get_weights(&self) -> HashMap<String, f64> {
        // Implementation for getting weights
        HashMap::new()
    }

    pub fn update_market_regime(&self, _regime: String /* MarketRegime */) {
        // Implementation for regime update
    }
}

#[derive(Debug)]
pub struct ModelPerformanceMetrics {
    model_id: String,
    accuracy: f64,
    recent_pnl: f64,
}

impl ModelPerformanceMetrics {
    pub fn new(model_id: String) -> Self {
        Self {
            model_id,
            accuracy: 0.5,
            recent_pnl: 0.0,
        }
    }

    pub fn update_performance(&mut self, accuracy: f64, pnl: f64, _config: &WeightConfig) {
        self.accuracy = accuracy;
        self.recent_pnl = pnl;
    }

    pub fn performance_score(&self) -> f64 {
        self.accuracy * 0.5 + (self.recent_pnl / 100.0) * 0.5
    }
}

pub fn calculate_entropy(weights: &HashMap<String, f64>) -> f64 {
    let total: f64 = weights.values().sum();
    if total <= 0.0 {
        return 0.0;
    }

    let mut entropy = 0.0;
    for &weight in weights.values() {
        if weight > 0.0 {
            let p = weight / total;
            entropy -= p * p.ln();
        }
    }
    entropy
}
