using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MarketData.Utils;
using MarketData.DataAccess;

namespace MarketData.MarketDataModel
{
  public class LotAggregator
  {
    private LotAggregator()
    {
    }
// combine multipe trades that share a common date, side, and price
// This is used specifically for the trade indicators in the Bollinger bands.
    public static PortfolioTrades CombineLots(List<PortfolioTrade> portfolioTrades)
    {
      Dictionary<String,PortfolioTrade> lots=new Dictionary<String,PortfolioTrade>();
      if (null == portfolioTrades||0==portfolioTrades.Count) return null;
      for(int index=0;index<portfolioTrades.Count;index++)
      {
        PortfolioTrade portfolioTrade=portfolioTrades[index];
        String key="";
        if(portfolioTrade.BuySell.Equals("B"))key=portfolioTrade.BuySell+portfolioTrade.TradeDate.Date.ToShortDateString()+"-"+Utility.FormatNumber(portfolioTrade.Price,3);
        else key=portfolioTrade.BuySell+portfolioTrade.TradeDate.Date.ToShortDateString()+"-"+Utility.FormatNumber(portfolioTrade.SellPrice,3); 
        if(!lots.ContainsKey(key)){lots.Add(key,portfolioTrade);} 
        else
        {
          PortfolioTrade tradeLot=lots[key];
          tradeLot.Shares+=portfolioTrade.Shares;
        }
      }
      PortfolioTrades combinedLots=new PortfolioTrades(lots.Values.OrderBy(x=>x.TradeDate).ToList());
      return combinedLots;
    }
  }
// *********************************************************************************************************************************************************
  public class PortfolioTrade
  {
    private int tradeId=-1;
    private String symbol;
    private DateTime tradeDate;
    private double shares;
    private double price;
    private double commission;
    private String buySell;
    private String account;
    private String status;
    private double sellPrice=double.NaN;
    private DateTime sellDate=Utility.Epoch;

    public int TradeId
    {
      get {return tradeId ;}
      set { tradeId = value; ;}
    }

    public String Symbol
    {
      get { return symbol; }
      set { symbol = value; }
    }

    public DateTime TradeDate
    {
      get { return tradeDate; }
      set { tradeDate = value; }
    }

    public double Shares
    {
      get { return shares; }
      set { shares = value; }
    }

    public double Exposure()
    {
      return Price*Shares;
    }

    public String BuySell
    {
      get { return buySell; }
      set { buySell = value; }
    }

    public String Status
    {
      get { return status; }
      set { status = value; }
    }

    public bool IsOpen
    {
      get { return status.ToUpper().Equals("OPEN"); }
    }

    public bool IsClosed
    {
      get { return !IsOpen; }
    }

    public String Account
    {
      get { return account; }
      set{account=value;}
    }

    public DateTime SellDate
    {
      get { return sellDate; }
      set { sellDate = value; }
    }

    public double SellPrice
    {
      get { return sellPrice;}
      set { sellPrice = value;}
    }

    public double Price
    {
      get { return price; }
      set { price = value; }
    }

    public double Commission
    {
      get { return commission; }
      set { commission = value; }
    }

    public virtual NVPCollection ToNVPCollection()
    {
      NVPCollection nvpCollection=new NVPCollection();
      nvpCollection.Add(new NVP("TradeId",TradeId.ToString()));
      if(null!=Symbol)nvpCollection.Add(new NVP("Symbol",Symbol.ToString()));
      nvpCollection.Add(new NVP("TradeDate",TradeDate.ToString()));
      nvpCollection.Add(new NVP("Shares",Shares.ToString()));
      nvpCollection.Add(new NVP("Commission",Commission.ToString()));
      if(null!=BuySell)nvpCollection.Add(new NVP("BuySell",BuySell.ToString()));
      if(null!=Account)nvpCollection.Add(new NVP("Account",Account.ToString()));
      if(null!=Status)nvpCollection.Add(new NVP("Status",Status.ToString()));
      nvpCollection.Add(new NVP("SellPrice",SellPrice.ToString()));
      nvpCollection.Add(new NVP("SellDate",SellDate.ToString()));
      nvpCollection.Add(new NVP("Price",Price.ToString()));
      return nvpCollection;
    }

    public static PortfolioTrade FromNVPCollection(NVPCollection nvpCollection)
    {
      PortfolioTrade portfolioTrade=new PortfolioTrade();

      NVPDictionary nvpDictionary=nvpCollection.ToDictionary();
      portfolioTrade.TradeId=nvpDictionary["TradeId"].Get<int>();
      portfolioTrade.Symbol=nvpDictionary["Symbol"].Get<String>();
      portfolioTrade.TradeDate=nvpDictionary["TradeDate"].Get<DateTime>();
      portfolioTrade.Shares=nvpDictionary["Shares"].Get<double>();
      portfolioTrade.Commission=nvpDictionary["Commission"].Get<double>();
      if(nvpDictionary.ContainsKey("BuySell"))portfolioTrade.BuySell=nvpDictionary["BuySell"].Get<String>();
      if(nvpDictionary.ContainsKey("Account"))portfolioTrade.Account=nvpDictionary["Account"].Get<String>();
      if(nvpDictionary.ContainsKey("Status"))portfolioTrade.Status=nvpDictionary["Status"].Get<String>();
      portfolioTrade.SellPrice=nvpDictionary["SellPrice"].Get<double>();
      portfolioTrade.SellDate=nvpDictionary["SellDate"].Get<DateTime>();
      portfolioTrade.Price=nvpDictionary["Price"].Get<double>();
      return portfolioTrade;
    }


  }
}
