using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Winbooks.TORM.OM.Accounting;

namespace Winbooks.Apis.Linker
{
    class ToolsALTransactions
    {
        public static void AddALTranss(Settings settings, GLTrans glTrans, IList<DetailALAccount> invoiceALAccounts, IList<ALTrans> alTranss)
        {
            int maxCount = 0;
            Dictionary<Guid, List<ALAccountIdAmount>> dims = new Dictionary<Guid, List<ALAccountIdAmount>>();
            foreach (DetailALAccount invoiceALAccount in invoiceALAccounts)
            {
                ALAccountIdAmount aLAccountIdAmount = new ALAccountIdAmount() { ALAccountId = invoiceALAccount.ALAccount.Id, Amount = invoiceALAccount.Sign.Equals("D") ? invoiceALAccount.Amount : -invoiceALAccount.Amount };
                List<ALAccountIdAmount> dim;
                if (dims.ContainsKey(invoiceALAccount.ALDimension.Id))
                    dim = dims[invoiceALAccount.ALDimension.Id];
                else
                {
                    dim = new List<ALAccountIdAmount>();
                    dims.Add(invoiceALAccount.ALDimension.Id, dim);
                }
                dim.Add(aLAccountIdAmount);
                if (dim.Count > maxCount)
                    maxCount = dim.Count;
            }
            for (int line = 0; line < maxCount; line++)  // lines
            {
                // ALTrans
                /////////////
                ALTrans aLTrans = new ALTrans()
                {
                    CommentBooking = glTrans.CommentBooking,
                    Currency_Id = glTrans.Currency_Id,
                    Currency = glTrans.Currency,
                    GLTrans_Id = glTrans.Id,
                    LineOrder = line,
                    Amount = 0,
                    ALTransactionDimensions = new List<ALTransactionDimension>()
                };
                if (settings.ALBookingMethod == ALBookingMethod.SameAmountForAllDimensions)
                {
                    // search the currencyAmount and check that they are all the same
                    decimal? currencyAmount = null;
                    foreach (var keyValue in dims) // key = ALDimensionId, value = List<ALAccountIdAmount>
                        if (keyValue.Value.Count > line)
                        {
                            if (currencyAmount == null)
                                currencyAmount = keyValue.Value[line].Amount;
                            else
                            {
                                if (currencyAmount != keyValue.Value[line].Amount)
                                    throw new ArgumentException(string.Format("InvoiceGLAccount.ALAccounts: The amounts for the row {0} must be all the same", line + 1));
                            }
                        }
                    aLTrans.CurrencyAmount = currencyAmount;
                    if (aLTrans.CurrencyAmount != null && glTrans.Currency != null && glTrans.Currency.Code != settings.FolderCurrency)
                        aLTrans.Amount = decimal.Round((decimal)aLTrans.CurrencyAmount / (decimal)glTrans.CurrencyRate, 2);
                    else
                        aLTrans.Amount = currencyAmount == null ? 0 : (decimal)currencyAmount;
                }

                // ALTransactionDimension
                ////////////////////////////
                foreach (var keyValue in dims) // key = ALDimensionId, value = List<ALAccountIdAmount>
                {
                    if (keyValue.Value.Count > line)
                    {
                        ALTransactionDimension aLTransactionDimension = new ALTransactionDimension()
                        {
                            ALAccount_Id = keyValue.Value[line].ALAccountId,
                            ALDimension_Id = keyValue.Key,
                        };
                        if (settings.ALBookingMethod == ALBookingMethod.OneAmountPerDimension)
                        {
                            aLTransactionDimension.CurrencyAmount = keyValue.Value[line].Amount;
                            if (aLTransactionDimension.CurrencyAmount != null && glTrans.Currency != null && glTrans.Currency.Code != settings.FolderCurrency)
                                aLTransactionDimension.Amount = decimal.Round((decimal)aLTransactionDimension.CurrencyAmount / (decimal)glTrans.CurrencyRate, 2);
                        }
                        aLTrans.ALTransactionDimensions.Add(aLTransactionDimension);
                    }
                }
                alTranss.Add(aLTrans);
            }
        }
    }

    class ALAccountIdAmount
    {
        public Guid ALAccountId { get; set; }
        public decimal Amount { get; set; }
    }
}
