using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleResponsibilityPrinciple
{
    public class TradeProcessor
    {
        public void ProcessTrades(Stream stream)
        {
            // Odczytanie wierszy.
            var lines = new List<string>();
            using (var reader = new StreamReader(stream))
            {
                string line;
                while((line = reader.ReadLine()) != null)
                {
                    lines.Add(line);
                }
            }

            var trades = new List<TradeRecord>();

            var lineCount = 1;
            foreach (var line in lines)
            {
                var fields = line.Split(new char[] { ',' });

                if(fields.Length != 3)
                {
                    Console.WriteLine("UWAGA: Błędny wiersz {0}. Zawiera tylko {1} pole/pola.", lineCount, fields.Length);
                    continue;
                }

                if(fields[0].Length != 6)
                {
                    Console.WriteLine("UWAGA: Błędna waluta w wierszu {0}: '{1}'", lineCount, fields[0]);
                    continue;
                }

                int tradeAmount;
                if(!int.TryParse(fields[1], out tradeAmount))
                {
                    Console.WriteLine("UWAGA: Błędna liczba akcji w wierszu {0}: '{1}'", lineCount, fields[1]);
                }

                decimal tradePrice;
                if(!decimal.TryParse(fields[2], out tradePrice))
                {
                    Console.WriteLine("UWAGA: Błędna wartość akcji w wierszu {0}: '{1}'", lineCount, fields[2]);
                }

                var sourceCurrencyCode = fields[0].Substring(0, 3);
                var destinationCurrencyCode = fields[0].Substring(3, 3);

                // Obliczenie wartości.
                var trade = new TradeRecord
                {
                    SourceCurrency = sourceCurrencyCode,
                    DestinationCurrency = destinationCurrencyCode,
                    Lots = tradeAmount / LotSize,
                    Price = tradePrice
                };

                trades.Add(trade);

                lineCount++;
            }

            using (var connection = new System.Data.SqlClient.SqlConnection("Data Source=(local);Initial Catalog=TradeDatabase;Integrated Security=True;"))
            {
                connection.Open();
                using(var transaction = connection.BeginTransaction())
                {
                    foreach(var trade in trades)
                    {
                        var command = connection.CreateCommand();
                        command.Transaction = transaction;
                        command.CommandType = System.Data.CommandType.StoredProcedure;
                        command.CommandText = "dbo.insert_trade";
                        command.Parameters.AddWithValue("@sourceCurrency", trade.SourceCurrency);
                        command.Parameters.AddWithValue("@destinationCurrency", trade.DestinationCurrency);
                        command.Parameters.AddWithValue("@lots", trade.Lots);
                        command.Parameters.AddWithValue("@price", trade.Price);

                        command.ExecuteNonQuery();
                    }

                    transaction.Commit();
                }
                connection.Close();
            }

            Console.WriteLine("INFO: Przetworzonych transakcji: {0}", trades.Count);
        }

        private static float LotSize = 100000f;
    }
}
