﻿using AutoMapper.QueryableExtensions;
using CashCreditCalculator.AprCalculator;
using CashCreditCalculator.Data.Contracts;
using CashCreditCalculator.Web.Controllers.Base;
using CashCreditCalculator.Web.Models;
using Microsoft.VisualBasic;
using System;
using System.Linq;
using System.Web.Mvc;

namespace CashCreditCalculator.Web.Controllers
{
    [Authorize]
    public class CalculateCreditController : BaseController
    {
        public CalculateCreditController(ICashCreditCalculatorData data)
            : base(data)
        {
        }

        [HttpGet]
        public ActionResult AllCashProviders()
        {
            var cashProviders = this.Data.CashProviders
                .All()
                .Where(cp => cp.IsApproved == true)
                .Project()
                .To<CashProviderViewModel>()
                .OrderBy(cp => cp.UserName)
                .ToList();

            return this.View(cashProviders);
        }

        [HttpGet]
        public ActionResult CheckCredit(string id)
        {
            CreditViewModel model = new CreditViewModel() { CashProviderId = id };
            return this.View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CalculateCredit(CreditViewModel viewModel)
        {
            var cashProvider = this.Data.CashProviders.All().Project().To<CashProviderViewModel>().FirstOrDefault(cp => cp.Id == viewModel.CashProviderId);
            double interestRate = (this.GetInterestRatePercentage(viewModel.Term, cashProvider) / 1200);
            double interestPayment = 1 - 1 / Math.Pow(1 + interestRate, viewModel.Term);
            decimal insurance = viewModel.IsInsured ? viewModel.CashAmount * (decimal)cashProvider.InterestRateStrategy.Insurrance / 100 : 0;
            double creditAmount = (double)viewModel.CashAmount + cashProvider.InterestRateStrategy.Insurrance;
            double monthlyPayment = (interestRate * creditAmount) / interestPayment;
            double totalAmount = monthlyPayment * viewModel.Term;
            int numOfFlows = viewModel.Term;

            //
            var aprCalculator = new APRCalculator((double)viewModel.CashAmount);
            aprCalculator.AddRegularInstalments(monthlyPayment, numOfFlows, InstalmentFrequency.Monthly);
            var apr = aprCalculator.Calculate();

            CalculatedCreditViewModel model = new CalculatedCreditViewModel
            {
                CreditAmount = Math.Round(creditAmount, 2),
                CashProviderId = viewModel.CashProviderId,
                Creditor = cashProvider.Creditor,
                Insurance = viewModel.IsInsured ? "Included" : "Not included",
                InterestRatePerYear = Math.Round(interestRate * 1200, 2),
                CreditAmountAfterInterest = Math.Round(totalAmount, 2),
                InterestAmount = Math.Round(totalAmount - creditAmount, 2),
                Term = viewModel.Term,
                MonthlyPayment = Math.Round(monthlyPayment, 2),
                Apr = apr,
                InterestRate = this.GetInterestRatePercentage(viewModel.Term, cashProvider)
            };

            return this.PartialView("_CalculatedCredit", model);
        }

        [HttpGet]
        public ActionResult DownloadEuroFormAsPdf(CalculatedCreditViewModel calculatedCreditModel)
        {
            var cashProviderModel = this.Data.CashProviders
                .All().Project()
                .To<CashProviderViewModel>()
                .FirstOrDefault(cp => cp.Id == calculatedCreditModel.CashProviderId);

            var euroFormModel = new EuroFormViewModel() { CashProvider = cashProviderModel, CalculatedCredit = calculatedCreditModel };
            //return new Rotativa.PartialViewAsPdf("_EuroForm") { CustomSwitches = "--disable-smart-shrinking" };
            return new Rotativa.ViewAsPdf("EuroForm", euroFormModel) { FileName = "EuroForm.pdf" };
        }

        [NonAction]
        private double GetInterestRatePercentage(int term, CashProviderViewModel model)
        {
            double interestRate = 0;

            switch (term)
            {
                case 3: interestRate = model.InterestRateStrategy.ThreeMonthRate;
                    break;
                case 6: interestRate = model.InterestRateStrategy.SixMonthsRate;
                    break;
                case 9: interestRate = model.InterestRateStrategy.NineMonthRate;
                    break;
                case 12: interestRate = model.InterestRateStrategy.TwelveMonthsRate;
                    break;
                case 15: interestRate = model.InterestRateStrategy.FifteenMonthsRate;
                    break;
                case 18: interestRate = model.InterestRateStrategy.EighteenMonthsRate;
                    break;
                case 21: interestRate = model.InterestRateStrategy.TwentyOneMonthsRate;
                    break;
                case 24: interestRate = model.InterestRateStrategy.TwentyFourMonthsRate;
                    break;
                default:
                    break;
            }

            return interestRate;
        }
    }
}