using System;
using System.Collections.Generic;

namespace NT8.Core.Intelligence
{
    /// <summary>
    /// Volatility classification for current market conditions.
    /// </summary>
    public enum VolatilityRegime
    {
        /// <summary>
        /// Very low volatility, expansion likely.
        /// </summary>
        Low = 0,

        /// <summary>
        /// Below normal volatility.
        /// </summary>
        BelowNormal = 1,

        /// <summary>
        /// Normal volatility band.
        /// </summary>
        Normal = 2,

        /// <summary>
        /// Elevated volatility, caution required.
        /// </summary>
        Elevated = 3,

        /// <summary>
        /// High volatility.
        /// </summary>
        High = 4,

        /// <summary>
        /// Extreme volatility, defensive posture.
        /// </summary>
        Extreme = 5
    }

    /// <summary>
    /// Trend classification for current market direction and strength.
    /// </summary>
    public enum TrendRegime
    {
        /// <summary>
        /// Strong uptrend.
        /// </summary>
        StrongUp = 0,

        /// <summary>
        /// Weak uptrend.
        /// </summary>
        WeakUp = 1,

        /// <summary>
        /// Ranging or neutral market.
        /// </summary>
        Range = 2,

        /// <summary>
        /// Weak downtrend.
        /// </summary>
        WeakDown = 3,

        /// <summary>
        /// Strong downtrend.
        /// </summary>
        StrongDown = 4
    }

    /// <summary>
    /// Quality score for observed trend structure.
    /// </summary>
    public enum TrendQuality
    {
        /// <summary>
        /// No reliable trend quality signal.
        /// </summary>
        Poor = 0,

        /// <summary>
        /// Trend quality is fair.
        /// </summary>
        Fair = 1,

        /// <summary>
        /// Trend quality is good.
        /// </summary>
        Good = 2,

        /// <summary>
        /// Trend quality is excellent.
        /// </summary>
        Excellent = 3
    }

    /// <summary>
    /// Snapshot of current market regime for a symbol.
    /// </summary>
    public class RegimeState
    {
        /// <summary>
        /// Instrument symbol.
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Current volatility regime.
        /// </summary>
        public VolatilityRegime VolatilityRegime { get; set; }

        /// <summary>
        /// Current trend regime.
        /// </summary>
        public TrendRegime TrendRegime { get; set; }

        /// <summary>
        /// Volatility score relative to normal baseline.
        /// </summary>
        public double VolatilityScore { get; set; }

        /// <summary>
        /// Trend strength from -1.0 (strong down) to +1.0 (strong up).
        /// </summary>
        public double TrendStrength { get; set; }

        /// <summary>
        /// Time the regime state was last updated.
        /// </summary>
        public DateTime LastUpdate { get; set; }

        /// <summary>
        /// Time spent in the current regime.
        /// </summary>
        public TimeSpan RegimeDuration { get; set; }

        /// <summary>
        /// Supporting indicator values for diagnostics.
        /// </summary>
        public Dictionary<string, object> Indicators { get; set; }

        /// <summary>
        /// Creates a new regime state.
        /// </summary>
        /// <param name="symbol">Instrument symbol.</param>
        /// <param name="volatilityRegime">Volatility regime.</param>
        /// <param name="trendRegime">Trend regime.</param>
        /// <param name="volatilityScore">Volatility score relative to normal.</param>
        /// <param name="trendStrength">Trend strength in range [-1.0, +1.0].</param>
        /// <param name="lastUpdate">Last update timestamp.</param>
        /// <param name="regimeDuration">Current regime duration.</param>
        /// <param name="indicators">Supporting indicators map.</param>
        public RegimeState(
            string symbol,
            VolatilityRegime volatilityRegime,
            TrendRegime trendRegime,
            double volatilityScore,
            double trendStrength,
            DateTime lastUpdate,
            TimeSpan regimeDuration,
            Dictionary<string, object> indicators)
        {
            if (string.IsNullOrEmpty(symbol))
                throw new ArgumentNullException("symbol");
            if (trendStrength < -1.0 || trendStrength > 1.0)
                throw new ArgumentException("trendStrength must be between -1.0 and 1.0", "trendStrength");

            Symbol = symbol;
            VolatilityRegime = volatilityRegime;
            TrendRegime = trendRegime;
            VolatilityScore = volatilityScore;
            TrendStrength = trendStrength;
            LastUpdate = lastUpdate;
            RegimeDuration = regimeDuration;
            Indicators = indicators ?? new Dictionary<string, object>();
        }
    }

    /// <summary>
    /// Represents a transition event between two regime states.
    /// </summary>
    public class RegimeTransition
    {
        /// <summary>
        /// Symbol where transition occurred.
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Previous volatility regime.
        /// </summary>
        public VolatilityRegime PreviousVolatilityRegime { get; set; }

        /// <summary>
        /// New volatility regime.
        /// </summary>
        public VolatilityRegime CurrentVolatilityRegime { get; set; }

        /// <summary>
        /// Previous trend regime.
        /// </summary>
        public TrendRegime PreviousTrendRegime { get; set; }

        /// <summary>
        /// New trend regime.
        /// </summary>
        public TrendRegime CurrentTrendRegime { get; set; }

        /// <summary>
        /// Transition timestamp.
        /// </summary>
        public DateTime TransitionTime { get; set; }

        /// <summary>
        /// Optional transition reason.
        /// </summary>
        public string Reason { get; set; }

        /// <summary>
        /// Creates a regime transition record.
        /// </summary>
        /// <param name="symbol">Instrument symbol.</param>
        /// <param name="previousVolatilityRegime">Previous volatility regime.</param>
        /// <param name="currentVolatilityRegime">Current volatility regime.</param>
        /// <param name="previousTrendRegime">Previous trend regime.</param>
        /// <param name="currentTrendRegime">Current trend regime.</param>
        /// <param name="transitionTime">Transition time.</param>
        /// <param name="reason">Transition reason.</param>
        public RegimeTransition(
            string symbol,
            VolatilityRegime previousVolatilityRegime,
            VolatilityRegime currentVolatilityRegime,
            TrendRegime previousTrendRegime,
            TrendRegime currentTrendRegime,
            DateTime transitionTime,
            string reason)
        {
            if (string.IsNullOrEmpty(symbol))
                throw new ArgumentNullException("symbol");

            Symbol = symbol;
            PreviousVolatilityRegime = previousVolatilityRegime;
            CurrentVolatilityRegime = currentVolatilityRegime;
            PreviousTrendRegime = previousTrendRegime;
            CurrentTrendRegime = currentTrendRegime;
            TransitionTime = transitionTime;
            Reason = reason ?? string.Empty;
        }
    }

    /// <summary>
    /// Historical regime timeline for one symbol.
    /// </summary>
    public class RegimeHistory
    {
        /// <summary>
        /// Symbol associated with history.
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Current state snapshot.
        /// </summary>
        public RegimeState CurrentState { get; set; }

        /// <summary>
        /// Historical transition events.
        /// </summary>
        public List<RegimeTransition> Transitions { get; set; }

        /// <summary>
        /// Creates a regime history model.
        /// </summary>
        /// <param name="symbol">Instrument symbol.</param>
        /// <param name="currentState">Current regime state.</param>
        /// <param name="transitions">Transition timeline.</param>
        public RegimeHistory(
            string symbol,
            RegimeState currentState,
            List<RegimeTransition> transitions)
        {
            if (string.IsNullOrEmpty(symbol))
                throw new ArgumentNullException("symbol");

            Symbol = symbol;
            CurrentState = currentState;
            Transitions = transitions ?? new List<RegimeTransition>();
        }
    }
}
