using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using MarketData.CSVHelper;

namespace MarketData.MarketDataModel
{
	public class EconomicIndicators : List<EconomicIndicator>
	{
	  public EconomicIndicators()
		{
    }
    public List<Int32> GetYears()
    {
      if(0==Count)return null;
      List<Int32> years=(from EconomicIndicator economicIndicator in this select economicIndicator.Year).Distinct().ToList();
      years.Sort();
      return years;
    }
    public Dictionary<String,EconomicIndicators> GetDictionary()
    {
      Dictionary<String,EconomicIndicators> dictionary=new Dictionary<String,EconomicIndicators>();
      if(0==Count)return null;
      for(int index=0;index<Count;index++)
      {
        EconomicIndicator economicIndicator=this[index];
        if(!dictionary.ContainsKey(economicIndicator.CountryCode))
        {
          List<EconomicIndicator> list=new List<EconomicIndicator>();
          dictionary.Add(economicIndicator.CountryCode,new EconomicIndicators());
        }                                                                                                              
        EconomicIndicators economicIndicators=dictionary[economicIndicator.CountryCode];
        economicIndicators.Add(economicIndicator);
      }
      List<String> keys=new List<String>(dictionary.Keys);
      foreach(String key in keys)
      {
        dictionary[key].Sort(new EconomicIndicatorByYear());
      }
      return dictionary;
    }
		public static EconomicIndicators FromZipFile(String strPathZipFile,String strPathExtractFolder,bool debug=false)
		{
			try
			{
				if(Directory.Exists(strPathExtractFolder))
				{
					try{Directory.Delete(strPathExtractFolder,true);}
					catch(Exception exception){MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Unable to delete folder {0}, exception was {1}",strPathExtractFolder,exception.ToString()));}
				}
				Directory.CreateDirectory(strPathExtractFolder);
				List<String> extractFiles=ExtractFileHelper.ExtractToFolder(strPathZipFile,strPathExtractFolder);
        if(null==extractFiles||0==extractFiles.Count)
				{
					MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Could not locate data in zip file {0}",strPathZipFile));
					return null;
				}
				String strPathExtractFile=(from String strPathExtractFileName in extractFiles where !strPathExtractFileName.Contains("Metadata") select strPathExtractFileName).FirstOrDefault();
        if(null==strPathExtractFile)
				{
					MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Could not locate data in zip file {0}",strPathZipFile));
					return null;
				}
				CSVFileExt2 csvFile=new CSVFileExt2();
				int dataRow=csvFile.FindLineWith(strPathExtractFile,"Country Name");
				if(-1==dataRow)
				{
				  MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Could not locate start of data in zip file {0}",strPathZipFile));
					return null;
				}
				csvFile.LoadCSVFile(strPathExtractFile,dataRow);
				if(0==csvFile.RowCount)
				{
					MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Could not locate data in zip file {0}",strPathZipFile));
					return null;
				}
        if(!debug)
        {
				  try{File.Delete(strPathZipFile);}
				  catch(Exception exception)
				  {
					  MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Could not remove zip file {0}, exception was {1}",strPathZipFile,exception.ToString()));
				  }
        }
				try{Directory.Delete(strPathExtractFolder,true);}
				catch(Exception exception)
				{
					MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error removing folder {0}, exception was {1}",strPathExtractFolder,exception.ToString()));
				}
			  return EconomicIndicators.FromDataTable(csvFile.ToDataTable());
			}
			catch(Exception exception)
			{
				MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error extracting economic indicators from zip file {0}, error was {1}",strPathZipFile,exception.ToString()));
				return null;
			}
		}
		public static EconomicIndicators FromDataTable(DataTable dataTable)
		{
  		String strValue=null;
			String strYear=null;
			try
			{
				EconomicIndicators economicIndicators=new EconomicIndicators();
				DataColumnCollection columns=dataTable.Columns;
				DataRowCollection rows=dataTable.Rows;

				for(int rowIndex=0;rowIndex<rows.Count;rowIndex++)
				{
					DataRow dataRow=rows[rowIndex];
					String countryName=dataRow[0].ToString();
					String countryCode=dataRow[1].ToString();
					String indicatorName=dataRow[2].ToString();
					String indicatorCode=dataRow[3].ToString();
					for(int columnIndex=4;columnIndex<columns.Count;columnIndex++)
					{
            EconomicIndicator economicIndicator=new EconomicIndicator();
            economicIndicator.CountryName=countryName;
            economicIndicator.CountryCode=countryCode;
            economicIndicator.IndicatorName=indicatorName;
            economicIndicator.IndicatorCode=indicatorCode;
            economicIndicator.Source="World Bank";
						strYear=columns[columnIndex].ToString();
						if("".Equals(strYear)||strYear.StartsWith("Column"))continue;
						economicIndicator.Year=int.Parse(strYear);
						strValue=dataRow[columnIndex].ToString();
						if("".Equals(strValue))continue;
						economicIndicator.IndicatorValue=Double.Parse(strValue);
						economicIndicators.Add(economicIndicator);
					}
				}
				return economicIndicators;
	    }
			catch(Exception exception)
			{
				MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
				return null;
			}
		}
	}
  public class EconomicIndicatorByYear : IComparer<EconomicIndicator>
  {
    public int Compare(EconomicIndicator p1,EconomicIndicator p2)
    {
      return p1.Year.CompareTo(p2.Year);
    }
  }
	public class EconomicIndicator
	{
		public String Source{get;set;}
		public String CountryName{get;set;}
		public String CountryCode{get;set;}
		public String IndicatorName{get;set;}
		public String IndicatorCode{get;set;}
    public double IndicatorValue{get;set;}
		public int Year{get;set;}
	}
}
