public ActionResult Register(RegisterViewModel viewModel)
        {

            using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
            {
                CryptoWalletDB.Domain.User user = new CryptoWalletDB.Domain.User();

                if( ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == viewModel.Email) ==null)
                {
                    ModelState.AddModelError("", "The email already exist!");

                    if (ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == viewModel.Name) == null)
                    {
                        ModelState.AddModelError("", "The name already exist!");
                    }
                                                                  }
                    return View(viewModel);
                }

               

                user.Email = viewModel.Email;
                user.Name = viewModel.Name;
                user.Password = viewModel.Password;

                ctx.Users.Add(user);
                ctx.SaveChanges();
                
            }
        public ActionResult Balance()
        {
            using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
            {
                User currentUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == User.Identity.Name);

                List <CryptoWalletDB.Domain.UserTransaction> allTransactions = ctx.UsersTransactions.Where(u =>
                                                                                                           u.FromAccount.UserId == currentUser.UserId &&
                                                                                                           u.ToAccount.UserId == currentUser.UserId &&
                                                                                                           u.ToAccountId != u.FromAccountId &&
                                                                                                           u.TransactionRate > 0 &&
                                                                                                           u.TransactionDate.Year == DateTime.Today.Year &&
                                                                                                           u.TransactionDate.Month >= DateTime.Today.Month - 1
                                                                                                           ).ToList();

                ExchangeService cryptoExchange = new ExchangeService();

                List <BalanceViewModel> viewModels = new List <BalanceViewModel>();

                foreach (CryptoWalletDB.Domain.UserTransaction item in allTransactions)
                {
                    //List<CurrencyRate> currencyRates = cryptoExchange.GetConversionRate(findCurrency(item.FromAccount.Currency), new Currency[] { findCurrency(item.ToAccount.Currency) });

                    viewModels.Add(new BalanceViewModel
                    {
                        DateTime     = item.TransactionDate,
                        Profit       = item.TransactionRate * item.Amount - cryptoExchange.GetConversionRate(findCurrency(item.FromAccount.Currency), new Currency[] { findCurrency(item.ToAccount.Currency) }).First().Rate *item.Amount,
                        FromCurrency = item.FromAccount.Currency,
                        ToCurrency   = item.ToAccount.Currency
                    });
                }

                return(View(viewModels));
            }
        }
        public ActionResult Login(LoginViewModel viewModel)
        {

            if (ModelState.IsValid)
            {
                using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
                {
                    CryptoWalletDB.Domain.User user = ctx.Users.FirstOrDefault(u => u.Email == viewModel.Username && u.Password == viewModel.Password);

                    if (user != null)
                    {
                        FormsAuthentication.SetAuthCookie(viewModel.Username, true);
                        return RedirectToAction("Index", "BankAccount");
                    }
                    else
                    {
                        ModelState.AddModelError("", "Invalid credentials!");
                        return View(viewModel);
                    }
                }
            }
            else
            { 
                return View(viewModel);
            }


        }
        private decimal TotalAmount()
        {
            using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
            {
                User currentUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == User.Identity.Name);

                List <CurrencyRate> rates = new ExchangeService().GetConversionRate(Currency.EUR, new Currency[] { Currency.USD, Currency.GBP, Currency.BTC, Currency.XRP });

                decimal totalAmount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == "EUR" && u.UserId == currentUser.UserId).Amount;

                UserBankAccount userBankAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == "USD" && u.UserId == currentUser.UserId);

                if (userBankAccount != null)
                {
                    rates = new ExchangeService().GetConversionRate(Currency.USD, new Currency[] { Currency.EUR });

                    totalAmount += (userBankAccount.Amount * rates.First().Rate);
                }

                userBankAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == "GBP" && u.UserId == currentUser.UserId);

                if (userBankAccount != null)
                {
                    rates = new ExchangeService().GetConversionRate(Currency.GBP, new Currency[] { Currency.EUR });

                    totalAmount += (userBankAccount.Amount * rates.First().Rate);
                }

                userBankAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == "BTC" && u.UserId == currentUser.UserId);

                if (userBankAccount != null)
                {
                    rates = new ExchangeService().GetConversionRate(Currency.BTC, new Currency[] { Currency.EUR });

                    totalAmount += (userBankAccount.Amount * rates.First().Rate);
                }

                userBankAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == "XRP" && u.UserId == currentUser.UserId);

                if (userBankAccount != null)
                {
                    rates = new ExchangeService().GetConversionRate(Currency.XRP, new Currency[] { Currency.EUR });

                    totalAmount += (userBankAccount.Amount * rates.First().Rate);
                }

                return(totalAmount);
            }
        }
        public ActionResult Deposit(DepositViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
                {
                    User currentUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == User.Identity.Name);

                    UserBankAccount eurAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == "EUR" && u.UserId == currentUser.UserId);

                    if (eurAccount == null)
                    {
                        eurAccount = new UserBankAccount
                        {
                            Currency = "EUR",
                            UserId   = currentUser.UserId,
                            Amount   = 0
                        };

                        ctx.UsersBankAccounts.Add(eurAccount);
                    }

                    eurAccount.Amount += viewModel.Amount;

                    ctx.SaveChanges();

                    UserTransaction transaction = new UserTransaction
                    {
                        Amount          = viewModel.Amount,
                        FromAccountId   = eurAccount.AccountId,
                        ToAccountId     = eurAccount.AccountId,
                        TransactionDate = DateTime.Now
                    };

                    ctx.UsersTransactions.Add(transaction);

                    ctx.SaveChanges();
                }
                return(RedirectToAction("Index"));
            }

            return(View(viewModel));
        }
        public ActionResult Index()
        {
            using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
            {
                List <UserBankAccount> accounts = ctx.Users.FirstOrDefault(u => u.Email == User.Identity.Name).UserBankAccounts.ToList();

                decimal totalAmount = TotalAmount();

                List <BankAccountViewModel> accountsViewModel = accounts.Select(a => new BankAccountViewModel
                {
                    totalAmount = totalAmount,
                    AccountId   = a.AccountId,
                    Amount      = a.Amount,
                    Currency    = a.Currency
                }).ToList();

                return(View(accountsViewModel));
            }
        }
        private void SetupConvertViewModel(ConvertViewModel viewModel)
        {
            using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
            {
                List <UserBankAccount> accounts = ctx.Users.FirstOrDefault(u => u.Email == User.Identity.Name).UserBankAccounts.ToList();

                List <ConvertViewModel> accountsViewModel = accounts.Select(a => new ConvertViewModel
                {
                    Amount       = a.Amount,
                    Currency     = a.Currency,
                    IntoCurrency = a.Currency
                }).ToList();

                viewModel.Currencies.AddRange(accountsViewModel.Select(a => new SelectListItem
                {
                    Value = a.Currency.ToString(),
                    Text  = a.Currency.ToString()
                }));
            }
        }
        public ActionResult History()
        {
            using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
            {
                User currentUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == User.Identity.Name);

                List <CryptoWalletDB.Domain.UserTransaction> allTransactions = ctx.UsersTransactions.Where(u => u.FromAccount.UserId == currentUser.UserId || u.ToAccount.UserId == currentUser.UserId).ToList();

                List <HistoryViewModel> HistoryViewModel = allTransactions.Select(a => new HistoryViewModel
                {
                    Rate            = a.TransactionRate,
                    Amount          = a.Amount,
                    Currency        = a.FromAccount.Currency,
                    FromEmail       = (ctx.UsersBankAccounts.FirstOrDefault(m => m.AccountId == a.FromAccountId).User).Email,
                    ToEmail         = (ctx.UsersBankAccounts.FirstOrDefault(m => m.AccountId == a.ToAccountId).User).Email,
                    From            = a.FromAccount,
                    To              = a.ToAccount,
                    TransactionDate = a.TransactionDate
                }).ToList();

                return(View(HistoryViewModel));
            }
        }
        public ActionResult Convert(ConvertViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
                {
                    User CurrentUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == User.Identity.Name);

                    UserBankAccount toAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == viewModel.IntoCurrency && u.UserId == CurrentUser.UserId);

                    UserBankAccount fromAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == viewModel.Currency && u.UserId == CurrentUser.UserId);

                    if (toAccount.Currency == fromAccount.Currency)
                    {
                        ModelState.AddModelError("", "Choose other currency!");

                        SetupConvertViewModel(viewModel);

                        return(View(viewModel));
                    }

                    if (fromAccount.Amount < viewModel.Amount)
                    {
                        ModelState.AddModelError("", "Insufficient funds!");

                        SetupConvertViewModel(viewModel);

                        return(View(viewModel));
                    }

                    ExchangeService cryptoExchange = new ExchangeService();

                    List <CurrencyRate> currencyRates = cryptoExchange.GetConversionRate(findCurrency(viewModel.Currency), new Currency[] { Currency.USD, Currency.GBP, Currency.BTC, Currency.XRP, Currency.EUR });

                    decimal rate = currencyRates.FirstOrDefault(u => u.Currency.ToString() == viewModel.IntoCurrency).Rate;

                    fromAccount.Amount -= viewModel.Amount;

                    toAccount.Amount += (viewModel.Amount * rate);

                    UserTransaction transaction = new UserTransaction
                    {
                        Amount          = viewModel.Amount,
                        ToAccountId     = toAccount.AccountId,
                        FromAccountId   = fromAccount.AccountId,
                        TransactionDate = DateTime.Now,
                        TransactionRate = (decimal)rate,
                        ToAccount       = toAccount,
                        FromAccount     = fromAccount
                    };

                    ctx.UsersTransactions.Add(transaction);

                    ctx.SaveChanges();

                    return(RedirectToAction("Index"));
                }
            }

            SetupConvertViewModel(viewModel);

            return(View(viewModel));
        }
        public ActionResult Send(SendViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                using (CryptoWalletDBContext ctx = new CryptoWalletDBContext())
                {
                    User fromUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == User.Identity.Name);

                    User toUser = ctx.Users.AsNoTracking().FirstOrDefault(u => u.Email == viewModel.ToUserEmail);

                    if (toUser != null)
                    {
                        if (fromUser.UserId == toUser.UserId)
                        {
                            ModelState.AddModelError("", "You can not send yourself!");

                            SetupSendViewModel(viewModel);

                            return(View(viewModel));
                        }

                        UserBankAccount toAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == viewModel.Currency && u.UserId == toUser.UserId);

                        UserBankAccount fromAccount = ctx.UsersBankAccounts.FirstOrDefault(u => u.Currency == viewModel.Currency && u.UserId == fromUser.UserId);

                        if (toAccount == null)
                        {
                            ModelState.AddModelError("", "The receiver does not have an account!");

                            SetupSendViewModel(viewModel);

                            return(View(viewModel));
                        }

                        if (fromAccount.Amount > viewModel.Amount)
                        {
                            fromAccount.Amount -= viewModel.Amount;

                            toAccount.Amount += viewModel.Amount;

                            UserTransaction transaction = new UserTransaction
                            {
                                Amount          = viewModel.Amount,
                                ToAccountId     = toAccount.AccountId,
                                FromAccountId   = fromAccount.AccountId,
                                TransactionDate = DateTime.Now,
                                TransactionRate = 1,
                                ToAccount       = toAccount,
                                FromAccount     = fromAccount
                            };

                            ctx.UsersTransactions.Add(transaction);

                            ctx.SaveChanges();

                            return(RedirectToAction("Index"));
                        }
                        else
                        {
                            ModelState.AddModelError("", "Insufficient funds!");

                            SetupSendViewModel(viewModel);

                            return(View(viewModel));
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "Invalid friend's email!");

                        SetupSendViewModel(viewModel);

                        return(View(viewModel));
                    }
                }
            }

            SetupSendViewModel(viewModel);

            return(View(viewModel));
        }