using Microsoft.EntityFrameworkCore;
using StockFin.Models;

namespace StockFin.ViewModels
{
    public class AccountState
    {
        public static AccountState FromAccount(Int64 accountid)
        {
            using (FinancesContext db = new FinancesContext())
            {
                Account account = db.Accounts.Include(a => a.Statements).SingleOrDefault(a => a.Id == accountid);
                if (account == null)
                {
                    return new AccountState { Id = 0, Bank = "", Title = "", ActualValue = 0, TypeId = null };
                }
                
                try
                {
                    Statement laststate = account.Statements.OrderByDescending(st => st.Date).First();
                    return (new AccountState { Id = account.Id, Bank = account.Bank, Title = account.Title, ActualValue = laststate.Value, TypeId = account.TypeId });
                }
                catch (Exception ex)
                {
                    return (new AccountState { Id = account.Id, Bank = account.Bank, Title = account.Title, ActualValue = 0, TypeId = account.TypeId });
                }

            }
        }
        public static AccountState FromPatrimony(Int64 accountid)
        {
            using (FinancesContext db = new FinancesContext())
            {
                Account account = db.Accounts.Include(a => a.Patrimonies).Include(a=>a.Increase).SingleOrDefault(a => a.Id == accountid);
                if (account == null)
                {
                    return new AccountState { Id = 0, Bank = "", Title = "", StartValue = 0, ActualValue = 0, TypeId = null };
                }
                
                try
                {
                    double actualvalue = 0;
                    double startvalue = 0;
                    var patrimonies = account.Patrimonies.OrderByDescending(st => st.BuyingDate);
                    foreach (Patrimony patrimony in patrimonies)
                    {
                        var patrimonyvalue = (patrimony.Price ?? 0) * (patrimony.Quantity ?? 0);
                        DateOnly buyingDate = patrimony.BuyingDate ?? DateOnly.FromDateTime(DateTime.Now);
                        DateOnly today = DateOnly.FromDateTime(DateTime.Now);
                        double patrimonydate = (today.DayNumber - buyingDate.DayNumber) / 365.25;
                        startvalue = startvalue + patrimonyvalue;
                        actualvalue = actualvalue + (patrimonyvalue * Math.Pow(1 + (account.Increase?.Value/100 ?? 0), patrimonydate));
                    }
                    return (new AccountState { Id = account.Id, Bank = account.Bank, Title = account.Title,StartValue=startvalue,  ActualValue = actualvalue, TypeId = account.TypeId });
                }
                catch (Exception ex)
                {
                    return (new AccountState { Id = account.Id, Bank = account.Bank, Title = account.Title,StartValue = 0, ActualValue = 0, TypeId = account.TypeId });
                }

            }
        }
        public static async Task<AccountState> FromStocks(Int64 accountid, StocksCache Cache)
        {
            using (FinancesContext db = new FinancesContext())
            {
                
                Account account = db.Accounts.Include(a => a.Transactions).ThenInclude(a=>a.Stocks).SingleOrDefault(a => a.Id == accountid);
                if (account == null)
                {
                    return new AccountState { Id = 0, Bank = "", Title = "", ActualValue = 0, TypeId = null };
                }
                
                try
                {
                    double? buyvalue = 0;
                    double? actualvalue = 0;
                    List<Stock> stocks = account.Transactions
                            .Where(t => t.Stocks != null)
                            .Select(t => t.Stocks!)
                            .GroupBy(s => s.Id)
                            .Select(g => g.First())
                            .ToList();

                    
                    foreach (Stock stock in stocks)
                    {
                        var quote = Cache.actuals.ContainsKey(stock.Ticker) ? Cache.actuals[stock.Ticker] : null;
                        double? subactualvalue = 0;
                        foreach (Transaction transaction in account.Transactions.Where(t => t.StocksId == stock.Id))
                        {
                            if (transaction.TypeId == 1)
                            {
                                buyvalue += transaction.Value*transaction.Quantity;
                                subactualvalue += transaction.Quantity;
                            }
                            else if (transaction.TypeId == 2)
                            {
                                buyvalue -= transaction.Value*transaction.Quantity;
                                subactualvalue -= transaction.Quantity;
                            }
                        }
                        if (quote != null)
                        {
                            subactualvalue *= quote;
                        }
                        else
                            { actualvalue = 0; }
                        actualvalue += subactualvalue;
                    }
                    return (new AccountState { Id = account.Id, Bank = account.Bank, Title = account.Title,StartValue=buyvalue??0, ActualValue = actualvalue ?? 0, TypeId = account.TypeId });
                
                }
                
                catch (Exception ex)
                {
                    return (new AccountState { Id = account.Id, Bank = account.Bank, Title = account.Title,StartValue=0, ActualValue = 0, TypeId = account.TypeId });
                }

            }
        }
        public long Id { get; set; }
        public string Bank { get; set; }
        public string Title { get; set; }

        public double StartValue { get; set; }
        public double LastMonthValue { get; set; }
        public double ActualValue { get; set; }
        public Int64? TypeId { get; set; }
    }
}
