using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace NT8.Core.Common.Models
{
    /// <summary>
    /// Bar data model
    /// </summary>
    public class BarData
    {
        /// <summary>
        /// Trading symbol
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Bar timestamp
        /// </summary>
        public DateTime Time { get; set; }

        /// <summary>
        /// Opening price
        /// </summary>
        public double Open { get; set; }

        /// <summary>
        /// Highest price
        /// </summary>
        public double High { get; set; }

        /// <summary>
        /// Lowest price
        /// </summary>
        public double Low { get; set; }

        /// <summary>
        /// Closing price
        /// </summary>
        public double Close { get; set; }

        /// <summary>
        /// Trading volume
        /// </summary>
        public long Volume { get; set; }

        /// <summary>
        /// Bar size/timeframe
        /// </summary>
        public TimeSpan BarSize { get; set; }

        /// <summary>
        /// Constructor for BarData
        /// </summary>
        public BarData(
            string symbol,
            DateTime time,
            double open,
            double high,
            double low,
            double close,
            long volume,
            TimeSpan barSize)
        {
            Symbol = symbol;
            Time = time;
            Open = open;
            High = high;
            Low = low;
            Close = close;
            Volume = volume;
            BarSize = barSize;
        }
    }

    /// <summary>
    /// Tick data model
    /// </summary>
    public class TickData
    {
        /// <summary>
        /// Trading symbol
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Tick timestamp
        /// </summary>
        public DateTime Time { get; set; }

        /// <summary>
        /// Tick price
        /// </summary>
        public double Price { get; set; }

        /// <summary>
        /// Tick size/quantity
        /// </summary>
        public int Size { get; set; }

        /// <summary>
        /// Tick type
        /// </summary>
        public TickType Type { get; set; }

        /// <summary>
        /// Constructor for TickData
        /// </summary>
        public TickData(
            string symbol,
            DateTime time,
            double price,
            int size,
            TickType type)
        {
            Symbol = symbol;
            Time = time;
            Price = price;
            Size = size;
            Type = type;
        }
    }

    /// <summary>
    /// Tick type enumeration
    /// </summary>
    public enum TickType
    {
        /// <summary>
        /// Trade tick
        /// </summary>
        Trade,

        /// <summary>
        /// Bid tick
        /// </summary>
        Bid,

        /// <summary>
        /// Ask tick
        /// </summary>
        Ask,

        /// <summary>
        /// Last traded price tick
        /// </summary>
        Last
    }

    /// <summary>
    /// Market data provider interface
    /// </summary>
    public interface IMarketDataProvider
    {
        /// <summary>
        /// Subscribe to bar data
        /// </summary>
        void SubscribeBars(string symbol, TimeSpan barSize, Action<BarData> onBar);

        /// <summary>
        /// Subscribe to tick data
        /// </summary>
        void SubscribeTicks(string symbol, Action<TickData> onTick);

        /// <summary>
        /// Get historical bars
        /// </summary>
        Task<List<BarData>> GetHistoricalBars(string symbol, TimeSpan barSize, int count);

        /// <summary>
        /// Get current market price
        /// </summary>
        double? GetCurrentPrice(string symbol);
    }
}