using System;

namespace NT8.Core.Execution
{
    /// <summary>
    /// Configuration for multiple profit targets
    /// </summary>
    public class MultiLevelTargets
    {
        /// <summary>
        /// Ticks for first target (TP1)
        /// </summary>
        public int TP1Ticks { get; set; }

        /// <summary>
        /// Number of contracts to close at first target
        /// </summary>
        public int TP1Contracts { get; set; }

        /// <summary>
        /// Ticks for second target (TP2) - nullable
        /// </summary>
        public int? TP2Ticks { get; set; }

        /// <summary>
        /// Number of contracts to close at second target - nullable
        /// </summary>
        public int? TP2Contracts { get; set; }

        /// <summary>
        /// Ticks for third target (TP3) - nullable
        /// </summary>
        public int? TP3Ticks { get; set; }

        /// <summary>
        /// Number of contracts to close at third target - nullable
        /// </summary>
        public int? TP3Contracts { get; set; }

        /// <summary>
        /// Constructor for MultiLevelTargets
        /// </summary>
        /// <param name="tp1Ticks">Ticks for first target</param>
        /// <param name="tp1Contracts">Contracts to close at first target</param>
        /// <param name="tp2Ticks">Ticks for second target</param>
        /// <param name="tp2Contracts">Contracts to close at second target</param>
        /// <param name="tp3Ticks">Ticks for third target</param>
        /// <param name="tp3Contracts">Contracts to close at third target</param>
        public MultiLevelTargets(
            int tp1Ticks,
            int tp1Contracts,
            int? tp2Ticks = null,
            int? tp2Contracts = null,
            int? tp3Ticks = null,
            int? tp3Contracts = null)
        {
            if (tp1Ticks <= 0)
                throw new ArgumentException("TP1Ticks must be positive", "tp1Ticks");
            if (tp1Contracts <= 0)
                throw new ArgumentException("TP1Contracts must be positive", "tp1Contracts");

            TP1Ticks = tp1Ticks;
            TP1Contracts = tp1Contracts;
            TP2Ticks = tp2Ticks;
            TP2Contracts = tp2Contracts;
            TP3Ticks = tp3Ticks;
            TP3Contracts = tp3Contracts;
        }
    }

    /// <summary>
    /// Configuration for trailing stops
    /// </summary>
    public class TrailingStopConfig
    {
        /// <summary>
        /// Type of trailing stop
        /// </summary>
        public StopType Type { get; set; }

        /// <summary>
        /// Trailing amount in ticks
        /// </summary>
        public int TrailingAmountTicks { get; set; }

        /// <summary>
        /// Trailing amount as percentage (for percentage-based trailing)
        /// </summary>
        public decimal? TrailingPercentage { get; set; }

        /// <summary>
        /// ATR multiplier for ATR-based trailing
        /// </summary>
        public decimal AtrMultiplier { get; set; }

        /// <summary>
        /// Whether to trail by high/low (true) or close prices (false)
        /// </summary>
        public bool TrailByExtremes { get; set; }

        /// <summary>
        /// Constructor for TrailingStopConfig
        /// </summary>
        /// <param name="type">Type of trailing stop</param>
        /// <param name="trailingAmountTicks">Trailing amount in ticks</param>
        /// <param name="atrMultiplier">ATR multiplier</param>
        /// <param name="trailByExtremes">Whether to trail by extremes</param>
        public TrailingStopConfig(
            StopType type,
            int trailingAmountTicks,
            decimal atrMultiplier = 2m,
            bool trailByExtremes = true)
        {
            if (trailingAmountTicks <= 0)
                throw new ArgumentException("TrailingAmountTicks must be positive", "trailingAmountTicks");
            if (atrMultiplier <= 0)
                throw new ArgumentException("AtrMultiplier must be positive", "atrMultiplier");

            Type = type;
            TrailingAmountTicks = trailingAmountTicks;
            AtrMultiplier = atrMultiplier;
            TrailByExtremes = trailByExtremes;
        }

        /// <summary>
        /// Constructor for percentage-based trailing stop
        /// </summary>
        /// <param name="trailingPercentage">Trailing percentage</param>
        /// <param name="trailByExtremes">Whether to trail by extremes</param>
        public TrailingStopConfig(decimal trailingPercentage, bool trailByExtremes = true)
        {
            if (trailingPercentage <= 0 || trailingPercentage > 100)
                throw new ArgumentException("TrailingPercentage must be between 0 and 100", "trailingPercentage");

            Type = StopType.PercentageTrailing;
            TrailingPercentage = trailingPercentage;
            TrailByExtremes = trailByExtremes;
        }
    }

    /// <summary>
    /// Configuration for automatic breakeven
    /// </summary>
    public class AutoBreakevenConfig
    {
        /// <summary>
        /// Number of ticks in profit before moving stop to breakeven
        /// </summary>
        public int TicksToBreakeven { get; set; }

        /// <summary>
        /// Whether to add a safety margin to breakeven stop
        /// </summary>
        public bool UseSafetyMargin { get; set; }

        /// <summary>
        /// Safety margin in ticks when moving to breakeven
        /// </summary>
        public int SafetyMarginTicks { get; set; }

        /// <summary>
        /// Whether to enable auto-breakeven
        /// </summary>
        public bool Enabled { get; set; }

        /// <summary>
        /// Constructor for AutoBreakevenConfig
        /// </summary>
        /// <param name="ticksToBreakeven">Ticks in profit before breakeven</param>
        /// <param name="useSafetyMargin">Whether to use safety margin</param>
        /// <param name="safetyMarginTicks">Safety margin in ticks</param>
        /// <param name="enabled">Whether enabled</param>
        public AutoBreakevenConfig(
            int ticksToBreakeven,
            bool useSafetyMargin = true,
            int safetyMarginTicks = 1,
            bool enabled = true)
        {
            if (ticksToBreakeven <= 0)
                throw new ArgumentException("TicksToBreakeven must be positive", "ticksToBreakeven");
            if (safetyMarginTicks < 0)
                throw new ArgumentException("SafetyMarginTicks cannot be negative", "safetyMarginTicks");

            TicksToBreakeven = ticksToBreakeven;
            UseSafetyMargin = useSafetyMargin;
            SafetyMarginTicks = safetyMarginTicks;
            Enabled = enabled;
        }
    }

    /// <summary>
    /// Stop type enumeration
    /// </summary>
    public enum StopType
    {
        /// <summary>
        /// Fixed stop at specific price
        /// </summary>
        Fixed = 0,

        /// <summary>
        /// Trailing stop by fixed ticks
        /// </summary>
        FixedTrailing = 1,

        /// <summary>
        /// Trailing stop by ATR multiple
        /// </summary>
        ATRTrailing = 2,

        /// <summary>
        /// Chandelier-style trailing stop
        /// </summary>
        Chandelier = 3,

        /// <summary>
        /// Parabolic SAR trailing stop
        /// </summary>
        ParabolicSAR = 4,

        /// <summary>
        /// Percentage-based trailing stop
        /// </summary>
        PercentageTrailing = 5
    }

    /// <summary>
    /// Target type enumeration
    /// </summary>
    public enum TargetType
    {
        /// <summary>
        /// Fixed target at specific price
        /// </summary>
        Fixed = 0,

        /// <summary>
        /// R-Multiple based target (based on risk amount)
        /// </summary>
        RMultiple = 1,

        /// <summary>
        /// Percentage-based target
        /// </summary>
        Percentage = 2,

        /// <summary>
        /// Tick-based target
        /// </summary>
        Tick = 3
    }
}
