using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using BankTV.Consts;
using BankTV.Logger;
using System.Net;
using BankTV.Model.Stock;
using System.Globalization;
using System.Text.RegularExpressions;
using BankTV.Extensions;

namespace BankTV.Helpers.Stock
{
    class StockApiHelper
    {        

        private static string GetStockFilePath(string fileName)
        {
            try
            {
                if (String.IsNullOrEmpty(fileName))
                {
                    return null;
                }   //if
                string stockFolder = GlobalHelper.GetStockFolder();
                if (String.IsNullOrEmpty(stockFolder))
                {
                    throw new Exception("Unable to get stock folder.");
                }   //if
                return System.IO.Path.Combine(stockFolder, fileName);
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return null;
            }   //catch
        }

        private static StockItem ConvertRowToStockItem(string stockRow)
        {
            if (String.IsNullOrWhiteSpace(stockRow))
            {
                return null;
            }   //if
            string[] stockElements = stockRow.Split(',');
            if (stockElements == null)
            {
                return null;
            }   //if
            if (stockElements.Count() < GlobalConsts.MIN_STOCK_ELEMENTS_COUNT)
            {
                return null;
            }   //if
            int counter = 0;
            StockItem stockItem = new StockItem();
            foreach (string stockElement in stockElements)
            {
                switch (counter)
                {
                    case 0:
                        if (!GlobalConsts.STOCK_ACCEPTABLE_NAMES.Contains(stockElement))
                        {
                            return null;
                        }   //if
                        stockItem.Name = stockElement;
                        break;
                    case 1:
                        try
                        {
                            stockItem.EntryDate = DateTime.ParseExact(stockElement, "yyyyMMdd", CultureInfo.InvariantCulture);
                        }
                        catch
                        {
                            stockItem.EntryDate = DateTime.Now;
                        }
                        break;
                    case 2:
                        try
                        {
                            stockItem.Opening = decimal.Parse(stockElement, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            MyLogger.Log(ex);
                            return null;
                        }
                        break;
                    case 3:
                        try
                        {
                            stockItem.Max = decimal.Parse(stockElement, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            MyLogger.Log(ex);
                            return null;
                        }
                        break;
                    case 4:
                        try
                        {
                            stockItem.Min = decimal.Parse(stockElement, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            MyLogger.Log(ex);
                            return null;
                        }
                        break;
                    case 5:
                        try
                        {
                            stockItem.Closing = decimal.Parse(stockElement, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            MyLogger.Log(ex);
                            return null;
                        }
                        break;
                    case 6:
                        try
                        {
                            stockItem.Trade = decimal.Parse(stockElement, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            MyLogger.Log(ex);
                            return null;
                        }
                        break;
                }   //switch
                counter++;
            }   //for
            return stockItem;
        }

        public static bool GetStockInfo(string url)
        {
            if (String.IsNullOrEmpty(url))
            {
                return false;
            }   //if
            try
            {
                GZipWebClient webClient = new GZipWebClient();                
                String stockData = webClient.DownloadString(url);
                if (String.IsNullOrWhiteSpace(stockData))
                {
                    return false;
                }   //if
                string tempStockFile = StockApiHelper.GetStockFilePath(StockApiHelper.GenerateStockLogFileName());
                if (!String.IsNullOrEmpty(tempStockFile))
                {
                    webClient.DownloadFile(url, tempStockFile);
                }   //if
                string[] stockItems = Regex.Split(stockData, @"\r?\n|\r");
                if (stockItems == null)
                {
                    return false;
                }   //if
                List<StockItem> newStockItems = new List<StockItem>();
                foreach (string stockRow in stockItems)
                {
                    StockItem stockItem = StockApiHelper.ConvertRowToStockItem(stockRow);                    
                    if (stockItem != null)
                    {
                        newStockItems.Add(stockItem);
                    }   //if
                }   //for
                return StockXmlHelper.SetStockXmlObject(newStockItems);                
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return false;
            }   //catch
        }

        private static string GenerateStockLogFileName()
        {
            return String.Format("stock-{0}.txt", DateTime.Now.ToString("yyyyMMdd", CultureInfo.InvariantCulture));
        }

        
    }

}
