using StockPortfolio.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Windows.Storage;

namespace StockPortfolio.Data
{
    public static class StockData
    {
       
        private static Random _rand = new Random();
        #region SymbolData Code

        public static Dictionary<string, string> StockSymbols = null;
        public static async Task<Dictionary<string, string>> LoadSymbolsAsync()
        {
            if (StockSymbols != null)
            {
                return StockSymbols;
            }
            StockSymbols = new Dictionary<string, string>();
            string resName = "Assets\\Symbols.txt";
            StorageFile txtFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(resName);
            var inputStream = await txtFile.OpenAsync(FileAccessMode.Read);
         
            using (StreamReader s = new StreamReader(inputStream.AsStreamForRead()))
            {
                while (!s.EndOfStream)
                {
                    string[] sn = s.ReadLine().Split('\t');
                    if (sn.Length == 2)
                        StockSymbols[sn[0]] = sn[1];
                }
            }
            return StockSymbols;
        }

        #endregion

        #region CurentStockData

        /// <summary>
        /// Returns Stock Quote of a given Symbol
        /// </summary>
        /// <param name="Symbol">Stock Symbol of the Stock</param>
        /// <returns></returns>
        public static async Task<StockQuotes> GetStockQuoteData(String Symbol)
        {

            StockQuotes _stockquote = new StockQuotes();

            try
            {
                string data = await MakeSymbolRequest(Symbol);
                //  data = data.Replace("r", "");
                if (data.Contains("html")||string.IsNullOrEmpty(data))
                {
                    GetStockMockData(Symbol, _stockquote);
                    return _stockquote;
                }

                string[] rows = Regex.Split(data, @"\r\n");

                for (int i = 0; i < rows.Length - 1; i++)
                {
                    if (rows[i].Replace("n", "").Trim() == "") continue;

                    string[] cols = rows[i].Split(',');

                    for (int j = 0; j < cols.Count(); j++)
                    {

                        if (cols[j] == "N/A")
                        {
                            cols[j] = "0";
                        }
                    }
                    
                    _stockquote.StockName = cols[0].Replace("\"", "");
                    _stockquote.StockSymbol = cols[1].Replace("\"", "");
                    _stockquote.StockExchange = cols[2].Replace("\"", "");
                    _stockquote.LastTrade = Convert.ToDouble(cols[3]);
                    // _stockquote.Change = Math.Round(Convert.ToDouble(cols[4])).ToString();
                    _stockquote.Change = cols[4];
                    _stockquote.PercentChange = cols[5];
                    _stockquote.Daylow = Convert.ToDouble(cols[6]);
                    _stockquote.Dayhigh = Convert.ToDouble(cols[7]);
                    _stockquote.Week52low = Convert.ToDouble(cols[8]);
                    _stockquote.Week52high = Convert.ToDouble(cols[9]);
                    _stockquote.MarketCap = cols[10];
                    _stockquote.Open = Convert.ToDouble(cols[11]);
                    _stockquote.PreviousClose = Convert.ToDouble(cols[12]);
                    _stockquote.LastTradeDate = Convert.ToDateTime(cols[13].Replace("\"", ""));
                }
            }
            catch (Exception)
            {
                GetStockMockData(Symbol, _stockquote);
            }
           

            return _stockquote;

        }

        private static void GetStockMockData(String Symbol, StockQuotes _stockquote)
        {
            int upOrdown = _rand.Next(0, 2);

            double basicvalue = _rand.Next(15, 30);
            double change = double.Parse(_rand.NextDouble().ToString("F2"));
            change = upOrdown != 0 ? change : -change;

            _stockquote.StockName = Symbol;
            _stockquote.StockSymbol = Symbol;
            _stockquote.StockExchange ="NYSE";
            _stockquote.LastTrade = basicvalue+change;
            // _stockquote.Change = Math.Round(Convert.ToDouble(cols[4])).ToString();
            _stockquote.Change =change.ToString();
            _stockquote.PercentChange = (change/basicvalue).ToString("F2") + "%";
            _stockquote.Daylow = basicvalue - 0.22;
            _stockquote.Dayhigh = basicvalue + 0.22; ;
            _stockquote.Week52low = basicvalue - 0.42;
            _stockquote.Week52high = basicvalue + 0.42; ;
            _stockquote.MarketCap = "19.327B";
            _stockquote.Open = basicvalue+change+0.01;
            _stockquote.PreviousClose = basicvalue-change;
            _stockquote.LastTradeDate = DateTime.Today;

        }

      

        public static async Task<string> MakeSymbolRequest(string symbol)
        {
            HttpClient http = new System.Net.Http.HttpClient();
            HttpResponseMessage response = await http.GetAsync(string.Format("http://finance.yahoo.com/d/quotes.csv?s={0}&f=nsxl1c1p2ghjkj1opd1", symbol));
            return await response.Content.ReadAsStringAsync();
        }

        #endregion

        #region HistoricalStockData
        /// <summary>
        ///  This functions returns the Historical information of a stock  as HistoricalStock object
        /// </summary>
        /// <param name="symbol">Stock Symbol</param>
        /// <param name="FromDate">From Date</param>
        /// <param name="ToDate">To Date</param>
        /// <returns></returns>
        public static async Task<List<HistoricalStock>> GetStockHistoricalData(string symbol, DateTime FromDate, DateTime ToDate)
        {

                List<HistoricalStock> retval = new List<HistoricalStock>();

                try
                {
                    string data = await MakeHistoricalDataRequest(symbol, FromDate, ToDate);
                    if (data.Contains("html") || string.IsNullOrEmpty(data))
                    {
                        GetStockMockStockHistoricalData(retval, FromDate,  ToDate);
                        return retval;
                    }

                    data = data.Replace("r", "");

                    string[] rows = Regex.Split(data, @"\n");

                    //First row is headers so Ignore it
                    for (int i = 1; i < rows.Length; i++)
                    {
                        if (rows[i].Replace("n", "").Trim() == "") continue;

                        string[] cols = rows[i].Split(',');

                        HistoricalStock hs = new HistoricalStock();
                        hs.Id = Guid.NewGuid();
                        hs.Date = Convert.ToDateTime(cols[0]);
                        hs.Open = Convert.ToDouble(cols[1]);
                        hs.High = Convert.ToDouble(cols[2]);
                        hs.Low = Convert.ToDouble(cols[3]);
                        hs.Close = Convert.ToDouble(cols[4]);
                        hs.Volume = Convert.ToDouble(cols[5]);
                        hs.AdjClose = Convert.ToDouble(cols[6]);

                        retval.Add(hs);
                    }
                }
                catch (Exception)
                {

                    GetStockMockStockHistoricalData(retval,  FromDate,  ToDate);
                    return retval;
                }
                

                return retval;
        }

        private static void GetStockMockStockHistoricalData(List<HistoricalStock> retval, DateTime FromDate, DateTime ToDate)
        {
            int count = (int)ToDate.Subtract(FromDate).TotalDays;
            for (int i = 0; i < count; i++)
            {
                var value = double.Parse(_rand.NextDouble().ToString("F2"));
                        HistoricalStock hs = new HistoricalStock();
                        hs.Id = Guid.NewGuid();
                        hs.Date = FromDate.Subtract(new TimeSpan(i,0,0,0));
                        hs.Open = value-0.32;
                        hs.High = value + 0.5;
                        hs.Low = value - 0.5;
                        hs.Close = value+0.32;
                        hs.Volume = _rand.Next(10000,1000000);
                        hs.AdjClose = value;
                        retval.Add(hs);
            }
        }

        private static async Task<string> MakeHistoricalDataRequest(string symbol, DateTime FromDate, DateTime ToDate)
        {
            HttpClient http = new System.Net.Http.HttpClient();
            HttpResponseMessage response = await http.GetAsync(string.Format("http://ichart.finance.yahoo.com/table.csv?s={0}&d={1}&e={2}&f={3}&g={4}&a={5}&b={6}&c={7}&ignore.csv", symbol, ToDate.Month - 1, ToDate.Day, ToDate.Year, "d", FromDate.Month - 1, FromDate.Day, FromDate.Year));
            return await response.Content.ReadAsStringAsync();
        }
        #endregion

     
    }
}
