using System;
using System.Linq;
using System.Web.Mvc;

using NUnit.Framework;
using MvcContrib.TestHelper;
using Platnosci.Controllers;

using Platnosci.Core.Interface;
using Platnosci.Core.Linq;
using Platnosci.Models;

namespace Platnosci.Tests.Web
{
    [TestFixture]   
    class PlatnosciControllerTests
    {
        private readonly ITranslateManager _translateManager = new FakeTranslation();
        private const string MERCHANT_NUMBER = "123";
        private readonly int _orderNumber = 9999;
        private const string CODE_OK = "payment_deposited";        //transakcja potwierdzona do rozliczenia
        private const string CODE_BAD = "payment_declined";        //transakcja odrzucona 
        private readonly DateTime _data = DateTime.Now;
        private readonly Function _function = new Function();
               
        [Test]
        [Category("Unit")]
        public void Status_Saves_Correct_Transaction()
        {          
           var repository = new Repository<PlatnosciEcard>(new FakeDataContext());
           var platnosci = _function.CreateNewPayment(_orderNumber, false, DateTime.Now, 12345); 
           repository.Insert(platnosci);
           repository.SubmitChanges();
                
           IRepository<PotwierdzeniaEcard> rep = new Repository<PotwierdzeniaEcard>(new FakeDataContext());
           
           var builder = new TestControllerBuilder();
           var controller = new PlatnoscController(null, repository, rep, _translateManager);
           builder.InitializeController(controller);
           builder.Form.Add("MERCHANTNUMBER", MERCHANT_NUMBER);
           builder.Form.Add("AUTHTIME", DateTime.Now.ToString());
           builder.Form.Add("DATATRANSMISJI", DateTime.Now.ToString());
           builder.Form.Add("ORDERNUMBER", _orderNumber.ToString());
           builder.Form.Add("CURRENTSTATE", CODE_OK);           
           
           controller.Status();
           
           System.Diagnostics.Debug.WriteLine("rep:" + rep.Count() + " repPl: " + repository.Count() );

           var potwierdzeniaEcard = rep.Find(o => o.ORDERNUMBER == _orderNumber).SingleOrDefault();
           Assert.That(potwierdzeniaEcard.MERCHANTNUMBER, Is.EqualTo(MERCHANT_NUMBER));
           var paymentAfterUpdate = repository.FindOne(_orderNumber);
           System.Diagnostics.Debug.WriteLine("Status musi byc 'true'. Jest " + paymentAfterUpdate.Status);
           Assert.That(paymentAfterUpdate.Status, Is.EqualTo(true));            
        }
        [Test]
        [Category("Unit")]
        public void Status_Saves_Correct_Transaction_IncorrectUpdate()
        {
            var repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());
            var platnosci = _function.CreateNewPayment(_orderNumber, false, DateTime.Now, 12345);
            repPayment.Insert(platnosci);
            repPayment.SubmitChanges();
            IRepository<PotwierdzeniaEcard> repConfirm = new Repository<PotwierdzeniaEcard>(new FakeDataContext());
          
            var builder = new TestControllerBuilder();
            var controller = new PlatnoscController(null, repPayment, repConfirm, _translateManager);
            builder.InitializeController(controller);
            builder.Form.Add("MERCHANTNUMBER", MERCHANT_NUMBER);
            builder.Form.Add("AUTHTIME", DateTime.Now.ToString());
            builder.Form.Add("DATATRANSMISJI", DateTime.Now.ToString());
            builder.Form.Add("ORDERNUMBER", _orderNumber.ToString());
            builder.Form.Add("CURRENTSTATE", CODE_BAD);

            controller.Status();           
           
            var potwierdzeniaEcard = repConfirm.Find(o => o.ORDERNUMBER == _orderNumber).SingleOrDefault();
            Assert.That(potwierdzeniaEcard.MERCHANTNUMBER, Is.EqualTo(MERCHANT_NUMBER));
            
            var paymentAfterUpdate = repPayment.FindOne(_orderNumber);
            System.Diagnostics.Debug.WriteLine("Status musi byc 'false'. Jest " + paymentAfterUpdate.Status);
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(false));
        }
        
        [Test]
        [Category("Unit")]
        public void StatusIsUpdated()
        {
            IRepository<PlatnosciEcard> repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());
            PlatnosciEcard platnosc = _function.CreateNewPayment(_orderNumber, false, _data, 1);
            repPayment.Insert(platnosc);

            var controller = new PlatnoscController(null, repPayment, null, _translateManager);
            controller.UpdateStatus(_orderNumber, CODE_OK);

            var paymentAfterUpdate = repPayment.FindOne(_orderNumber);
            System.Diagnostics.Debug.WriteLine("Status musi byc 'true'. Jest " + paymentAfterUpdate.Status);
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(true));
        }
        [Test]
        [Category("Unit")]
        public void StatusIsNotUpdated()
        {
            IRepository<PlatnosciEcard> repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());

            PlatnosciEcard platnosc = _function.CreateNewPayment(_orderNumber, false, _data, 1);
            repPayment.Insert(platnosc);

            var controller = new PlatnoscController(null, repPayment, null, _translateManager);
            controller.UpdateStatus(_orderNumber, CODE_BAD);

            var paymentAfterUpdate = repPayment.FindOne(i => i.ORDERNUMBER == _orderNumber);
            System.Diagnostics.Debug.WriteLine("Status musi byc 'false'. Jest " + paymentAfterUpdate.Status);
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(false));
        }        
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_IncorrectUserIdentity_ReturnErrorView()
        {
            IRepository<vPlatnosciEcard> repVPayment = new Repository<vPlatnosciEcard>(new FakeDataContext());
            var platnosc = _function.CreateInvoice(123, "nip1", "", 0, 0);
            repVPayment.Insert(platnosc);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            controller.ControllerContext = _function.CreateControllerContext("nip2");
           
            var result = controller.Show("123","pl") as ViewResult;
            var error = (ErrorViewData)result.ViewData.Model;

            Assert.That(error.Error, Is.EqualTo("weryfikacja"));
            Assert.That(result.ViewName, Is.EqualTo("Error1"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_PaymentNotFound_ReturnErrorView()
        {
            IRepository<vPlatnosciEcard> repVPayment = new Repository<vPlatnosciEcard>(new FakeDataContext());
            vPlatnosciEcard platnosc = _function.CreateInvoice(123, "", "", 0, 0);
            repVPayment.Insert(platnosc);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            //controller.setBrakDanych("Platnosc o takim id nie istnieje");

            var result = controller.Show("1234", "pl") as ViewResult;
            var error = (ErrorViewData)result.ViewData.Model;

            Assert.That(error.Error, Is.EqualTo("brakdanych"));
            Assert.That(result.ViewName, Is.EqualTo("Error1"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_PaymentIsPaid()
        {
            //Tworzymy takie dane aby platnosc o danym id byla juz zaplacona 
            var repVPayment = new Repository<vPlatnosciEcard>(new FakeDataContext());
            var invoice = _function.CreateInvoice(123, "nip1", "aaa", 0, 0);
            repVPayment.Insert(invoice);
            repVPayment.SubmitChanges();

            var repConfirm = new Repository<PotwierdzeniaEcard>(new FakeDataContext());
            var confirm = _function.CreateConfirm(CODE_OK, 123456);
            repConfirm.Insert(confirm);
            repConfirm.SubmitChanges();

            var controller = new PlatnoscController(repVPayment, null, repConfirm, _translateManager);
            controller.ControllerContext = _function.CreateControllerContext("nip1");
            //controller.setZaplacono("Platnosc zostala uregulowana");

            var result = controller.Show("123", "pl") as ViewResult;
            var view = (InvoiceDetailsViewData)result.ViewData.Model;

            Assert.That(result.ViewName, Is.EqualTo("Paid"));
            Assert.That(view.info, Is.EqualTo("zaplacono"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_CorrectData_ReturnViewForPayment()
        {
            IRepository<vPlatnosciEcard> repVPayment = new Repository<vPlatnosciEcard>(new FakeDataContext());
            vPlatnosciEcard platnosc = _function.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(platnosc);

            var repConfirm = new Repository<PotwierdzeniaEcard>(new FakeDataContext());
            var confirm = _function.CreateConfirm(CODE_OK, 1);
            repConfirm.Insert(confirm);
            repConfirm.SubmitChanges();

            var controller = new PlatnoscController(repVPayment, null, repConfirm, _translateManager);
            controller.ControllerContext = _function.CreateControllerContext("nip1");

            var result = controller.Show("123", "pl") as ViewResult;
                      
            var view = (InvoiceDetailsViewData)result.ViewData.Model;
            System.Diagnostics.Debug.WriteLine("Brutto 200: " + view.vPlatnosciEcard.Brutto);
            System.Diagnostics.Debug.WriteLine("Nr Faktury musi byc 'numer'. Jest " + view.vPlatnosciEcard.Faktura_Numer);
            Assert.That(view.vPlatnosciEcard.Brutto, Is.EqualTo(200));
            Assert.That(view.vPlatnosciEcard.Faktura_Numer, Is.EqualTo("numer"));            
        }
        [Test]
        [Category("Unit")]
        public void AfterPay_PaymentIsNotValid()
        {
            IRepository<vPlatnosciEcard> repVPayment = new Repository<vPlatnosciEcard>(new FakeDataContext());
            vPlatnosciEcard platnosc = _function.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(platnosc);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            controller.ControllerContext = _function.CreateControllerContext("nip1");
            
            Payer payer = _function.CreatePayer(123, "", "test");  //Brak imienia
            controller.Show(payer, "pl");
            Assert.That(controller.ModelState.IsValid, Is.False);
        }
        [Test]
        [Category("Unit")]
        public void AfterPay_PaymentIsValid()
        {
            IRepository<vPlatnosciEcard> repVPayment = new Repository<vPlatnosciEcard>(new FakeDataContext());
            vPlatnosciEcard platnosc = _function.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(platnosc);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            controller.ControllerContext = _function.CreateControllerContext("nip1");

            var payer = _function.CreatePayer(123, "test", "test");  
            controller.Show(payer, "pl");

            System.Diagnostics.Debug.WriteLine("Model powinien byc 'true'. Jest " + controller.ModelState.IsValid);
            Assert.That(controller.ModelState.IsValid, Is.True);
        }
    }
}

