//! Comprehensive validation for ML models using unified common types

// Import types from appropriate modules
use crate::{MLError, MLResult};
use common::types::{Price, Quantity, Volume};
use serde::{Deserialize, Serialize};

/// Enhanced validation result with financial type validation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationResult {
    pub passed: bool,
    pub score: f64,
    pub message: String,
    /// Financial-specific validation results
    pub financial_validation: Option<FinancialValidationResult>,
}

/// Financial validation for trading-specific ML models
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FinancialValidationResult {
    pub price_validation: bool,
    pub volume_validation: bool,
    pub quantity_validation: bool,
    pub risk_metrics_validation: bool,
}

/// Comprehensive model validation using common types
pub fn validate_model_comprehensive(
    prices: &[Price],
    volumes: &[Volume],
    quantities: &[Quantity],
) -> MLResult<ValidationResult> {
    let mut financial_result = FinancialValidationResult {
        price_validation: true,
        volume_validation: true,
        quantity_validation: true,
        risk_metrics_validation: true,
    };

    // Validate prices using canonical Price type
    for price in prices {
        if price.to_f64() <= 0.0 {
            financial_result.price_validation = false;
            return Ok(ValidationResult {
                passed: false,
                score: 0.0,
                message: "Invalid price detected (non-positive)".to_owned(),
                financial_validation: Some(financial_result),
            });
        }
    }

    // Validate volumes using canonical Volume type
    for volume in volumes {
        if volume.to_f64() < 0.0 {
            financial_result.volume_validation = false;
            return Ok(ValidationResult {
                passed: false,
                score: 0.0,
                message: "Invalid volume detected (negative)".to_owned(),
                financial_validation: Some(financial_result),
            });
        }
    }

    // Validate quantities using canonical Quantity type
    for quantity in quantities {
        if quantity.to_f64() == 0.0 {
            financial_result.quantity_validation = false;
            return Ok(ValidationResult {
                passed: false,
                score: 0.5,
                message: "Zero quantity detected (may be valid)".to_owned(),
                financial_validation: Some(financial_result),
            });
        }
    }

    Ok(ValidationResult {
        passed: true,
        score: 0.95,
        message: "Comprehensive validation passed with unified types".to_owned(),
        financial_validation: Some(financial_result),
    })
}

/// Basic validation function (backward compatibility)
pub fn validate_model_basic() -> Result<ValidationResult, Box<dyn std::error::Error>> {
    Ok(ValidationResult {
        passed: true,
        score: 0.85,
        message: "Basic validation passed".to_owned(),
        financial_validation: None,
    })
}

/// Validate conversion between common types
pub fn validate_type_conversions() -> MLResult<()> {
    use crate::common::conversions::*;

    // Test Price ↔ f64 conversions using FromPrimitive trait
    let test_price = Price::from_f64(100.50).map_err(|e| MLError::ValidationError {
        message: format!("Price creation error: {}", e),
    })?;
    let f64_val = price_to_f64(test_price).map_err(|e| MLError::ValidationError {
        message: format!("Price to f64 error: {}", e),
    })?;
    let converted_back = f64_to_price(f64_val).map_err(|e| MLError::ValidationError {
        message: format!("Price conversion error: {}", e),
    })?;

    if (test_price.to_f64() - converted_back.to_f64()).abs() > 1e-6 {
        return Err(MLError::ValidationError {
            message: "Price conversion validation failed".to_owned(),
        });
    }

    // Test Volume ↔ f64 conversions using FromPrimitive trait
    let test_volume = Volume::from_f64(1000.0).map_err(|e| MLError::ValidationError {
        message: format!("Volume creation error: {}", e),
    })?;
    let f64_vol = volume_to_f64(test_volume).map_err(|e| MLError::ValidationError {
        message: format!("Volume to f64 error: {}", e),
    })?;
    let converted_vol = f64_to_volume(f64_vol).map_err(|e| MLError::ValidationError {
        message: format!("Volume conversion error: {}", e),
    })?;

    if (test_volume.to_f64() - converted_vol.to_f64()).abs() > 1e-6 {
        return Err(MLError::ValidationError {
            message: "Volume conversion validation failed".to_owned(),
        });
    }

    Ok(())
}
