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

namespace adMoto.Payments.Web.Controllers
{
    public class PlatnoscController : Controller
    {
        public const string ISPAID = "payment_deposited";       //transakcja potwierdzona do rozliczenia
        private readonly IRepository<Invoice> _repVPayment;
        private readonly IRepository<PlatnosciEcard> _repPayment;
        private readonly IRepository<PotwierdzeniaEcard> _repConfirm;
        private readonly ITranslateManager _translateManager;
        private readonly PaymentsUtils _paymentsUtils;

        public PlatnoscController()
        {
            _repVPayment = new Repository<Invoice>(new DataContext());
            _repPayment = new Repository<PlatnosciEcard>(new DataContext());
            _repConfirm = new Repository<PotwierdzeniaEcard>(new DataContext());
            _paymentsUtils = new PaymentsUtils(_repPayment);
            _translateManager = new Translation();
        }
        public PlatnoscController(IRepository<Invoice> repVPayment, IRepository<PlatnosciEcard> repPayment, IRepository<PotwierdzeniaEcard> repConfirm, ITranslateManager translate)
        {
            _repVPayment = repVPayment;
            _repPayment = repPayment;
            _repConfirm = repConfirm;
            _translateManager = translate;
            _paymentsUtils = new PaymentsUtils(_repPayment, _translateManager);

        }

        [Authorize]
        public ActionResult Show(string id, string language)
        {
            _paymentsUtils.SetLanguage(language);
            var id1 = ConvertId(id);

            var platnosc = _repVPayment.Find(p => p.ID_faktury == id1).SingleOrDefault();

            var errorViewData = _paymentsUtils.IsError(platnosc, HttpContext.User.Identity.Name);
            if (!String.IsNullOrEmpty(errorViewData.Error))
                return View("Error1", errorViewData);

            var invoiceDeatailsViewData = InitInvoiceDetailsViewData(platnosc);

            var tablicaPotwierdzenia = _repConfirm.FindItemsByIdFaktury(id1);
            if (tablicaPotwierdzenia.Count > 0) //platnosc za fakture zostala uregulowana
            {
                var dataZaplaty = String.Format("{0:dd-MM-yyyy}", tablicaPotwierdzenia[0].AUTHTIME);
                invoiceDeatailsViewData.Info = String.Format(_translateManager.Translate("tlumaczenia", "zaplacono"), platnosc.Faktura_Numer, dataZaplaty);
                invoiceDeatailsViewData.Termin = dataZaplaty;
                return View("Paid", invoiceDeatailsViewData);
            }
            return View(invoiceDeatailsViewData);
        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Show(Payer payer, string language)
        {
            _paymentsUtils.SetLanguage(language);

            if (String.IsNullOrEmpty(payer.FirstName))
                ModelState.AddModelError("Payer.FirstName", _translateManager.Translate("tlumaczenia", "err_imieWK"));
            else if (payer.FirstName.Length > 25)
                ModelState.AddModelError("Payer.FirstName", String.Format(_translateManager.Translate("tlumaczenia", "ToLongValue"), "25"));

            if (String.IsNullOrEmpty(payer.LastName))
                ModelState.AddModelError("Payer.LastName", _translateManager.Translate("tlumaczenia", "err_nazwiskoWK"));
            else if (payer.LastName.Length > 30)
                ModelState.AddModelError("Payer.LastName", String.Format(_translateManager.Translate("tlumaczenia", "ToLongValue"), "30"));

            if (ModelState.IsValid == false)
            {
                var platnosc = _repVPayment.Find(p => p.ID_faktury == payer.Id_faktury).SingleOrDefault();
                var errorViewData = _paymentsUtils.IsError(platnosc, HttpContext.User.Identity.Name);

                if (!String.IsNullOrEmpty(errorViewData.Error))
                    return View("Error1", errorViewData);

                return View("Show", InitInvoiceDetailsViewData(platnosc));
            }
            return RedirectToAction("Merchant", "Merchant", payer);
        }

        public ActionResult Ok(string id, string order, string language)
        {
            var orderId = ConvertId(order);
            _paymentsUtils.SetLanguage(language);
            var id1 = ConvertId(id);
            var platnosc = _repVPayment.Find(p => p.ID_faktury == id1).SingleOrDefault();

            if (platnosc == null)
                return View("Error1", _paymentsUtils.InitErrorViewData(_translateManager.Translate("tlumaczenia", "brakdanych"), 0));

            var invoiceDeatailsViewData = InitInvoiceDetailsViewData(platnosc);

            //sprawdzamy czy dla kombinacji ordernumber i idfaktury istnieje platnosc, 
            //jesli tak, to sprawdzamy czy przyszlo potwierdzenie z eCardu.             

            if (CheckConfirm(id1, orderId) == 0)   //nie ma potwierdzenia z eCardu
                invoiceDeatailsViewData.Info = String.Format(_translateManager.Translate("tlumaczenia", "blad1"), invoiceDeatailsViewData.Invoice.Faktura_Numer);

            else if (CheckConfirm(id1, orderId) == 2)
                invoiceDeatailsViewData.Info = _translateManager.Translate("tlumaczenia", "weryfikacja");

            return View(invoiceDeatailsViewData);
        }

        public ActionResult Fail(string id, string language)
        {
            _paymentsUtils.SetLanguage(language);
            var id1 = ConvertId(id);
            var platnosc = _repVPayment.Find(p => p.ID_faktury == id1).SingleOrDefault();

            if (platnosc == null)
                return View("Error1",
                            _paymentsUtils.InitErrorViewData(
                                _translateManager.Translate("tlumaczenia", "brakdanych"), 0));

            var invoiceDeatailsViewData = InitInvoiceDetailsViewData(platnosc);
            return View(invoiceDeatailsViewData);
        }

        public ActionResult Form()
        {
            return View();
        }

        public ActionResult Status()
        {
            if (System.Web.HttpContext.Current != null)
                ErrorSignal.FromCurrentContext().Raise(new Exception(), System.Web.HttpContext.Current);

            var potwierdzenie = new PotwierdzeniaEcard();
            var content = new ContentResult();
            try
            {
                if (!String.IsNullOrEmpty(Request["APPROVALCODE"]))
                    potwierdzenie.APPROVALCODE = Request["APPROVALCODE"];
                if (!String.IsNullOrEmpty(Request["AUTHTIME"]))
                    potwierdzenie.AUTHTIME = Convert.ToDateTime(Request["AUTHTIME"]);
                if (!String.IsNullOrEmpty(Request["BIN"])) potwierdzenie.BIN = Request["BIN"];
                if (!String.IsNullOrEmpty(Request["COMMTYPE"])) potwierdzenie.COMMTYPE = Request["COMMTYPE"];
                if (!String.IsNullOrEmpty(Request["CURRENTSTATE"]))
                    potwierdzenie.CURRENTSTATE = Request["CURRENTSTATE"];
                if (!String.IsNullOrEmpty(Request["DATATRANSMISJI"]))
                    potwierdzenie.DATATRANSMISJI = Convert.ToDateTime(Request["DATATRANSMISJI"]);
                if (!String.IsNullOrEmpty(Request["EVENTTYPE"]))
                    potwierdzenie.EVENTTYPE = Convert.ToBoolean(Request["EVENTTYPE"]);
                if (!String.IsNullOrEmpty(Request["MERCHANTNUMBER"]))
                    potwierdzenie.MERCHANTNUMBER = Request["MERCHANTNUMBER"];
                if (!String.IsNullOrEmpty(Request["ORDERNUMBER"]))
                    potwierdzenie.ORDERNUMBER = Convert.ToInt32(Request["ORDERNUMBER"]);
                if (!String.IsNullOrEmpty(Request["PAYMENTNUMBER"]))
                    potwierdzenie.PAYMENTNUMBER = Convert.ToBoolean(Request["PAYMENTNUMBER"]);
                if (!String.IsNullOrEmpty(Request["PAYMENTTYPE"]))
                    potwierdzenie.PAYMENTTYPE = Convert.ToBoolean(Request["PAYMENTTYPE"]);
                if (!String.IsNullOrEmpty(Request["PREVIOUSSTATE"]))
                    potwierdzenie.PREVIOUSSTATE = Request["PREVIOUSSTATE"];
                if (!String.IsNullOrEmpty(Request["TYPE"])) potwierdzenie.TYPE = Request["TYPE"];
                if (!String.IsNullOrEmpty(Request["VALIDATIONCODE"]))
                    potwierdzenie.VALIDATIONCODE = Request["VALIDATIONCODE"];
                if (!String.IsNullOrEmpty(Request["WITHCVC"])) potwierdzenie.WITHCVC = Request["WITHCVC"];

                if (!potwierdzenie.ORDERNUMBER.HasValue || potwierdzenie.ORDERNUMBER.Value <= 0)
                {
                    content.Content = "FALSE";
                    return content;
                }

                _repConfirm.Insert(potwierdzenie);

                if (potwierdzenie.ORDERNUMBER.HasValue)
                    UpdateStatus(potwierdzenie.ORDERNUMBER.Value, potwierdzenie.CURRENTSTATE);

                content.Content = "OK";
            }
            catch (Exception ex)
            {
                ErrorSignal.FromCurrentContext().Raise(ex);

                content.Content = "FALSE " + ex.Message + " " + ex.GetType();
            }

            return content;
        }

        private static Payer InitPayer(int idFaktury)
        {
            var payer = new Payer { Id_faktury = idFaktury };
            return payer;
        }

        private InvoiceDetailsViewData InitInvoiceDetailsViewData(Invoice platnosc)
        {
            var invoiceDeatailsViewData = new InvoiceDetailsViewData();
            invoiceDeatailsViewData.Invoice = platnosc;
            invoiceDeatailsViewData.Payer = InitPayer(platnosc.ID_faktury);
            invoiceDeatailsViewData.Brutto = _paymentsUtils.BruttoToString(platnosc.Brutto, platnosc.waluta_brutto, platnosc.waluta_miano);
            return invoiceDeatailsViewData;
        }

        public int ConvertId(string id)
        {
            int id1;
            return Int32.TryParse(id, out id1) ? id1 : 0;
        }

        public void UpdateStatus(int ordernumber, string currentstate)
        {
            var platnosc = _repPayment.Find(p => p.ORDERNUMBER == ordernumber).SingleOrDefault();

            if (platnosc != null && currentstate == ISPAID)
            {
                platnosc.Status = true;
                platnosc.Status_data = DateTime.Now;
                _repPayment.SubmitChanges();
            }
        }

        public int CheckConfirm(int idfaktury, int order)
        {
            var pl = _repPayment.Find(p => p.ORDERNUMBER == order && p.IDFaktury == idfaktury).SingleOrDefault();

            if (pl != null)
            {
                var confirm = _repConfirm.Find(p => p.ORDERNUMBER == order).FirstOrDefault();
                if (confirm == null) return 0; //potwierdzenie nie przyszlo z eCardu
            }
            else
            {
                return 2; //nie ma platnosci o takim idfaktury i ordernumber
            }

            return 1;    //potwierdzenie przyszlo z eCardu
        }
    }
}