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

namespace BackTester
{
    internal static class PortfolioManager
    {
        private static readonly double maxTradePositionSize = 10000000;
        internal static readonly double maxLossPerPosition = 1000;

        public static bool tryBuyStock(string symbol, StrategyBuyActionInfo buyActionInfo, DateTime tradeDate, out int quantity)
        {
            quantity = 0;
            var stockPrice = buyActionInfo.buyPrice;
            if (stockPrice > maxTradePositionSize)
            {
                return false;
            }

            quantity = (int)Math.Floor(maxLossPerPosition / (stockPrice - buyActionInfo.stopLoss));

            if ((quantity * stockPrice) > maxTradePositionSize)
            {
                quantity = (int)Math.Floor(maxTradePositionSize / stockPrice);
            }

            if (quantity == 0)
            {
                return false;
            }

            if (quantity < 0)
            {
                throw new Exception("Quantity cannot be zero");
            }

            OrderManager.AddOrder(new BuyOrderInfo()
            {
                price = stockPrice,
                quantity = quantity,
                tradeDate = tradeDate,
                extraInfo = buyActionInfo.extraBuyInfo
            }, symbol);

            return true;
        }

        public static void sell(string symbol, StrategySellActionInfo sellActionInfo, DateTime tradeDate)
        {
            OrderManager.AddOrder(new SellOrderInfo()
            {
                price = sellActionInfo.sellPrice,
                percentPositionSize = sellActionInfo.percentPositionSize,
                tradeDate = tradeDate,
                extraInfo = sellActionInfo.extraSellInfo
            }, symbol);
        }

        public static bool tryShortSell(string symbol, StrategySellShortActionInfo shortSellActionInfo, DateTime tradeDate, out int quantity)
        {
            quantity = 0;
            var shortSalePrice = shortSellActionInfo.shortSellPrice;
            if (shortSalePrice > maxTradePositionSize)
            {
                return false;
            }

            quantity = (int)Math.Floor(maxLossPerPosition / (shortSellActionInfo.stopLoss - shortSalePrice));

            if (quantity == 0)
            {
                return false;
            }

            if (quantity < 0)
            {
                throw new Exception("Quantity cannot be zero");
            }

            OrderManager.AddOrder(new ShortSellOrderInfo()
            {
                price = shortSalePrice,
                quantity = quantity,
                tradeDate = tradeDate,
                extraInfo = shortSellActionInfo.extraSellShortInfo
            }, symbol);

            return true;
        }

        public static void cover(string symbol, StrategyCoverActionInfo coverActionInfo, DateTime tradeDate)
        {
            OrderManager.AddOrder(new CoverOrderInfo()
            {
                price = coverActionInfo.coverPrice,
                percentPositionSize = coverActionInfo.percentPositionSize,
                tradeDate = tradeDate,
                extraInfo = coverActionInfo.extraCoverInfo
            }, symbol);
        }
    }
}