using System;
using System.Collections.Generic;
using NT8.Core.Common.Models;
using NT8.Core.Intelligence;

namespace NT8.Core.Analytics
{
    /// <summary>
    /// Time period used for analytics aggregation.
    /// </summary>
    public enum AnalyticsPeriod
    {
        /// <summary>
        /// Daily period.
        /// </summary>
        Daily,

        /// <summary>
        /// Weekly period.
        /// </summary>
        Weekly,

        /// <summary>
        /// Monthly period.
        /// </summary>
        Monthly,

        /// <summary>
        /// Lifetime period.
        /// </summary>
        AllTime
    }

    /// <summary>
    /// Represents one complete trade lifecycle.
    /// </summary>
    public class TradeRecord
    {
        /// <summary>
        /// Trade identifier.
        /// </summary>
        public string TradeId { get; set; }

        /// <summary>
        /// Trading symbol.
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Strategy name.
        /// </summary>
        public string StrategyName { get; set; }

        /// <summary>
        /// Entry timestamp.
        /// </summary>
        public DateTime EntryTime { get; set; }

        /// <summary>
        /// Exit timestamp.
        /// </summary>
        public DateTime? ExitTime { get; set; }

        /// <summary>
        /// Trade side.
        /// </summary>
        public OrderSide Side { get; set; }

        /// <summary>
        /// Quantity.
        /// </summary>
        public int Quantity { get; set; }

        /// <summary>
        /// Average entry price.
        /// </summary>
        public double EntryPrice { get; set; }

        /// <summary>
        /// Average exit price.
        /// </summary>
        public double? ExitPrice { get; set; }

        /// <summary>
        /// Realized PnL.
        /// </summary>
        public double RealizedPnL { get; set; }

        /// <summary>
        /// Unrealized PnL.
        /// </summary>
        public double UnrealizedPnL { get; set; }

        /// <summary>
        /// Confluence grade at entry.
        /// </summary>
        public TradeGrade Grade { get; set; }

        /// <summary>
        /// Confluence weighted score at entry.
        /// </summary>
        public double ConfluenceScore { get; set; }

        /// <summary>
        /// Risk mode at entry.
        /// </summary>
        public RiskMode RiskMode { get; set; }

        /// <summary>
        /// Volatility regime at entry.
        /// </summary>
        public VolatilityRegime VolatilityRegime { get; set; }

        /// <summary>
        /// Trend regime at entry.
        /// </summary>
        public TrendRegime TrendRegime { get; set; }

        /// <summary>
        /// Stop distance in ticks.
        /// </summary>
        public int StopTicks { get; set; }

        /// <summary>
        /// Target distance in ticks.
        /// </summary>
        public int TargetTicks { get; set; }

        /// <summary>
        /// R multiple for the trade.
        /// </summary>
        public double RMultiple { get; set; }

        /// <summary>
        /// Trade duration.
        /// </summary>
        public TimeSpan Duration { get; set; }

        /// <summary>
        /// Metadata bag.
        /// </summary>
        public Dictionary<string, object> Metadata { get; set; }

        /// <summary>
        /// Creates a new trade record.
        /// </summary>
        public TradeRecord()
        {
            Metadata = new Dictionary<string, object>();
        }
    }

    /// <summary>
    /// Per-trade metrics.
    /// </summary>
    public class TradeMetrics
    {
        /// <summary>
        /// Trade identifier.
        /// </summary>
        public string TradeId { get; set; }

        /// <summary>
        /// Gross PnL.
        /// </summary>
        public double PnL { get; set; }

        /// <summary>
        /// R multiple.
        /// </summary>
        public double RMultiple { get; set; }

        /// <summary>
        /// Maximum adverse excursion.
        /// </summary>
        public double MAE { get; set; }

        /// <summary>
        /// Maximum favorable excursion.
        /// </summary>
        public double MFE { get; set; }

        /// <summary>
        /// Slippage amount.
        /// </summary>
        public double Slippage { get; set; }

        /// <summary>
        /// Commission amount.
        /// </summary>
        public double Commission { get; set; }

        /// <summary>
        /// Net PnL.
        /// </summary>
        public double NetPnL { get; set; }

        /// <summary>
        /// Whether trade is a winner.
        /// </summary>
        public bool IsWinner { get; set; }

        /// <summary>
        /// Hold time.
        /// </summary>
        public TimeSpan HoldTime { get; set; }

        /// <summary>
        /// Return on investment.
        /// </summary>
        public double ROI { get; set; }

        /// <summary>
        /// Custom metrics bag.
        /// </summary>
        public Dictionary<string, object> CustomMetrics { get; set; }

        /// <summary>
        /// Creates a trade metrics model.
        /// </summary>
        public TradeMetrics()
        {
            CustomMetrics = new Dictionary<string, object>();
        }
    }

    /// <summary>
    /// Point-in-time portfolio performance snapshot.
    /// </summary>
    public class PerformanceSnapshot
    {
        /// <summary>
        /// Snapshot time.
        /// </summary>
        public DateTime Timestamp { get; set; }

        /// <summary>
        /// Equity value.
        /// </summary>
        public double Equity { get; set; }

        /// <summary>
        /// Cumulative PnL.
        /// </summary>
        public double CumulativePnL { get; set; }

        /// <summary>
        /// Drawdown percentage.
        /// </summary>
        public double DrawdownPercent { get; set; }

        /// <summary>
        /// Open positions count.
        /// </summary>
        public int OpenPositions { get; set; }
    }

    /// <summary>
    /// PnL attribution breakdown container.
    /// </summary>
    public class AttributionBreakdown
    {
        /// <summary>
        /// Attribution dimension.
        /// </summary>
        public string Dimension { get; set; }

        /// <summary>
        /// Total PnL.
        /// </summary>
        public double TotalPnL { get; set; }

        /// <summary>
        /// Dimension values with contribution amount.
        /// </summary>
        public Dictionary<string, double> Contributions { get; set; }

        /// <summary>
        /// Creates a breakdown model.
        /// </summary>
        public AttributionBreakdown()
        {
            Contributions = new Dictionary<string, double>();
        }
    }

    /// <summary>
    /// Aggregate performance metrics for a trade set.
    /// </summary>
    public class PerformanceMetrics
    {
        /// <summary>
        /// Total trade count.
        /// </summary>
        public int TotalTrades { get; set; }

        /// <summary>
        /// Win count.
        /// </summary>
        public int Wins { get; set; }

        /// <summary>
        /// Loss count.
        /// </summary>
        public int Losses { get; set; }

        /// <summary>
        /// Win rate [0,1].
        /// </summary>
        public double WinRate { get; set; }

        /// <summary>
        /// Loss rate [0,1].
        /// </summary>
        public double LossRate { get; set; }

        /// <summary>
        /// Gross profit.
        /// </summary>
        public double GrossProfit { get; set; }

        /// <summary>
        /// Gross loss absolute value.
        /// </summary>
        public double GrossLoss { get; set; }

        /// <summary>
        /// Net profit.
        /// </summary>
        public double NetProfit { get; set; }

        /// <summary>
        /// Average win.
        /// </summary>
        public double AverageWin { get; set; }

        /// <summary>
        /// Average loss absolute value.
        /// </summary>
        public double AverageLoss { get; set; }

        /// <summary>
        /// Profit factor.
        /// </summary>
        public double ProfitFactor { get; set; }

        /// <summary>
        /// Expectancy.
        /// </summary>
        public double Expectancy { get; set; }

        /// <summary>
        /// Sharpe ratio.
        /// </summary>
        public double SharpeRatio { get; set; }

        /// <summary>
        /// Sortino ratio.
        /// </summary>
        public double SortinoRatio { get; set; }

        /// <summary>
        /// Max drawdown percent.
        /// </summary>
        public double MaxDrawdownPercent { get; set; }

        /// <summary>
        /// Recovery factor.
        /// </summary>
        public double RecoveryFactor { get; set; }
    }

    /// <summary>
    /// Trade outcome classification.
    /// </summary>
    public enum TradeOutcome
    {
        /// <summary>
        /// Winning trade.
        /// </summary>
        Win,

        /// <summary>
        /// Losing trade.
        /// </summary>
        Loss,

        /// <summary>
        /// Flat trade.
        /// </summary>
        Breakeven
    }
}
