use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use crate::Position;
use super::{BacktestConfig, CompletedTrade};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BacktestMetrics {
    // Core Performance Metrics
    pub total_return: f64,
    pub total_return_pct: f64,
    pub annualized_return: f64,
    pub total_pnl: f64,
    pub net_pnl: f64, // After commissions
    
    // Risk Metrics
    pub sharpe_ratio: f64,
    pub sortino_ratio: f64,
    pub calmar_ratio: f64,
    pub max_drawdown: f64,
    pub max_drawdown_pct: f64,
    pub max_drawdown_duration_days: i64,
    pub volatility: f64,
    pub downside_deviation: f64,
    pub var_95: f64, // Value at Risk 95%
    pub cvar_95: f64, // Conditional VaR 95%
    
    // Trade Statistics
    pub total_trades: usize,
    pub winning_trades: usize,
    pub losing_trades: usize,
    pub breakeven_trades: usize,
    pub win_rate: f64,
    pub loss_rate: f64,
    pub avg_win: f64,
    pub avg_loss: f64,
    pub largest_win: f64,
    pub largest_loss: f64,
    pub avg_trade_pnl: f64,
    pub avg_trade_duration_hours: f64,
    pub profit_factor: f64,
    pub expectancy: f64,
    pub expectancy_ratio: f64,
    
    // Position Statistics
    pub avg_position_size: f64,
    pub max_position_size: f64,
    pub avg_positions_held: f64,
    pub max_concurrent_positions: usize,
    pub total_long_trades: usize,
    pub total_short_trades: usize,
    pub long_win_rate: f64,
    pub short_win_rate: f64,
    
    // Trading Activity
    pub total_volume_traded: f64,
    pub total_commission_paid: f64,
    pub commission_pct_of_pnl: f64,
    pub avg_daily_trades: f64,
    pub max_daily_trades: usize,
    pub trading_days: usize,
    pub exposure_time_pct: f64,
    
    // Efficiency Metrics
    pub return_over_max_dd: f64,
    pub win_loss_ratio: f64,
    pub kelly_criterion: f64,
    pub ulcer_index: f64,
    pub serenity_ratio: f64,
    pub lake_ratio: f64,
    
    // Monthly/Period Analysis
    pub best_month_return: f64,
    pub worst_month_return: f64,
    pub positive_months: usize,
    pub negative_months: usize,
    pub monthly_win_rate: f64,
    pub avg_monthly_return: f64,
    
    // Streak Analysis
    pub max_consecutive_wins: usize,
    pub max_consecutive_losses: usize,
    pub current_streak: i32, // Positive for wins, negative for losses
    pub avg_winning_streak: f64,
    pub avg_losing_streak: f64,
}

// Trade structure that matches web app expectations
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Trade {
    pub id: String,
    pub timestamp: DateTime<Utc>,
    pub symbol: String,
    pub side: String, // "buy" or "sell"
    pub quantity: f64,
    pub price: f64,
    pub commission: f64,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pnl: Option<f64>,
}

// Equity curve point
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EquityPoint {
    pub timestamp: i64, // milliseconds since epoch
    pub value: f64,
}

// Daily return data
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DailyReturn {
    pub date: String,
    pub value: f64,
}

// Performance data point for charts
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PerformanceDataPoint {
    pub timestamp: String,
    pub portfolio_value: f64,
    pub pnl: f64,
    pub drawdown: f64,
}

// Period returns (monthly, weekly, etc)
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PeriodReturn {
    pub period: String, // "2024-01", "2024-W01", etc
    pub start_date: String,
    pub end_date: String,
    pub return_pct: f64,
    pub pnl: f64,
    pub trades: usize,
    pub win_rate: f64,
}

// Trade analysis by symbol
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SymbolAnalysis {
    pub symbol: String,
    pub total_trades: usize,
    pub winning_trades: usize,
    pub losing_trades: usize,
    pub total_pnl: f64,
    pub win_rate: f64,
    pub avg_win: f64,
    pub avg_loss: f64,
    pub profit_factor: f64,
    pub total_volume: f64,
    pub avg_position_size: f64,
    pub exposure_time_pct: f64,
}

// Drawdown period information
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DrawdownPeriod {
    pub start_date: String,
    pub end_date: String,
    pub peak_value: f64,
    pub trough_value: f64,
    pub drawdown_pct: f64,
    pub recovery_date: Option<String>,
    pub duration_days: i64,
    pub recovery_days: Option<i64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BacktestResult {
    // Metadata
    pub backtest_id: String,
    pub status: String,
    pub started_at: String,
    pub completed_at: String,
    pub execution_time_ms: u64,
    
    // Configuration
    pub config: BacktestConfig,
    
    // Core Metrics
    pub metrics: BacktestMetrics,
    
    // Time Series Data
    pub equity_curve: Vec<EquityPoint>,
    pub drawdown_curve: Vec<EquityPoint>,
    pub daily_returns: Vec<DailyReturn>,
    pub cumulative_returns: Vec<EquityPoint>,
    
    // Trade Data
    pub trades: Vec<Trade>,
    pub open_trades: Vec<Trade>,
    pub trade_signals: Vec<TradeSignal>,
    
    // Position Data
    pub positions: HashMap<String, Position>,
    pub position_history: Vec<PositionSnapshot>,
    
    // Analytics
    pub monthly_returns: Vec<PeriodReturn>,
    pub yearly_returns: Vec<PeriodReturn>,
    pub symbol_analysis: HashMap<String, SymbolAnalysis>,
    pub drawdown_periods: Vec<DrawdownPeriod>,
    pub exposure_analysis: ExposureAnalysis,
    
    // Market Data
    pub ohlc_data: HashMap<String, Vec<serde_json::Value>>,
    
    // Error Handling
    #[serde(skip_serializing_if = "Option::is_none")]
    pub error: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub warnings: Option<Vec<String>>,
}

// Trade signal for visualization
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TradeSignal {
    pub timestamp: String,
    pub symbol: String,
    pub action: String, // "buy", "sell", "hold"
    pub strength: f64,
    pub reason: String,
}

// Position snapshot for tracking
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PositionSnapshot {
    pub timestamp: String,
    pub positions: HashMap<String, PositionDetail>,
    pub total_value: f64,
    pub cash: f64,
    pub margin_used: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PositionDetail {
    pub symbol: String,
    pub quantity: f64,
    pub avg_price: f64,
    pub current_price: f64,
    pub market_value: f64,
    pub unrealized_pnl: f64,
    pub unrealized_pnl_pct: f64,
}

// Exposure analysis
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExposureAnalysis {
    pub avg_gross_exposure: f64,
    pub avg_net_exposure: f64,
    pub max_gross_exposure: f64,
    pub max_net_exposure: f64,
    pub time_in_market_pct: f64,
    pub long_exposure_pct: f64,
    pub short_exposure_pct: f64,
}