using System;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using adMoto.Payments.Core;
using adMoto.Payments.Core.Data;
using adMoto.Payments.Core.Interfaces;
using adMoto.Payments.Web.Models;

namespace adMoto.Payments.Web.Controllers
{
    [HandleError]
    public class AccountController : Controller
    {
        private readonly IRepository<Invoice> _repository;
        private readonly PaymentsUtils _paymentsUtils;

        public IFormsAuthentication FormsAuth
        {
            get;
            private set;
        }

        public AccountController()
        {
            _repository = new Repository<Invoice>(new DataContext());
            FormsAuth = new FormsAuthenticationService();
            _paymentsUtils = new PaymentsUtils();
        }

        public AccountController(IFormsAuthentication formsAuth, IRepository<Invoice> repository, PaymentsUtils paymentsUtils)
        {
            _repository = repository;
            FormsAuth = formsAuth ?? new FormsAuthenticationService();
            _paymentsUtils = paymentsUtils;
        }

        public ActionResult LogOn(string language)
        {
            if (language != "pl" && language != "en" && language != "de")
                return RedirectToAction("LogOn", "Account", new { language = "pl" });

            _paymentsUtils.SetLanguage(language);
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
            Justification = "Needs to take same parameter type as Controller.Redirect()")]
        public ActionResult LogOn(string nip, string numerFaktury, string returnUrl, string language)
        {
            _paymentsUtils.SetLanguage(language);
            var invoice = new Invoice();
            
            if (!ValidateLogOn(nip, numerFaktury))
                return View();            
            
            invoice = _repository.FindInvoiceByNipNumber(nip, numerFaktury).SingleOrDefault();
            
            if (invoice == null) 
                return View();

            _paymentsUtils.SetUserLogger(nip, numerFaktury);

            FormsAuth.SignIn(nip, false);

            if (!String.IsNullOrEmpty(returnUrl))
                return Redirect(returnUrl);
            
            return RedirectToAction("Show", "Platnosc", new { id = invoice.ID_faktury });
        }

        public ActionResult LogOff()
        {
            FormsAuth.SignOut();
            return RedirectToAction("LogOn", "Account");
        }

        private bool ValidateLogOn(string nip, string numerFaktury)
        {
            var errNip = HttpContext.GetGlobalResourceObject("tlumaczenia", "err_nip").ToString();
            var errFaktura = HttpContext.GetGlobalResourceObject("tlumaczenia", "err_faktura").ToString();
            var errTxt = HttpContext.GetGlobalResourceObject("tlumaczenia", "err_logowanie").ToString(); 
   
            if (String.IsNullOrEmpty(nip))
                ModelState.AddModelError("nip", errNip);
            
            if (String.IsNullOrEmpty(numerFaktury))
                ModelState.AddModelError("numerFaktury", errFaktura);
            
            if (ModelState.IsValid)
            {
                var daneOk = _repository.Exists(u => u.Faktura_Numer == numerFaktury && u.nip == nip);
                if (daneOk == false)
                    ModelState.AddModelError("_FORM", errTxt);
            }
            return ModelState.IsValid;
        }
    }

    public interface IFormsAuthentication
    {
        void SignIn(string nip, bool createPersistentCookie);
        void SignOut();
    }

    public class FormsAuthenticationService : IFormsAuthentication
    {
        public void SignIn(string nip, bool createPersistentCookie)
        {
            FormsAuthentication.SetAuthCookie(nip, createPersistentCookie);
        }
        public void SignOut()
        {
            FormsAuthentication.SignOut();
        }
    }
}