using System;
using System.Web.Mvc;
using adMoto.Payments.Core;
using adMoto.Payments.Core.Data;
using adMoto.Payments.Core.Interfaces;
using adMoto.Payments.Test.Fakes;
using adMoto.Payments.Web.Controllers;
using adMoto.Payments.Web.Models;
using NUnit.Framework;

namespace adMoto.Payments.Test.Controllers
{
    [TestFixture]
    public 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 TestDataHelper _testDataHelper = new TestDataHelper();
               
        [Test]
        [Category("Unit")]
        public void Update_Status_Payment_Is_Update_When_Currentstate_Is_CODE_OK()
        {
            //Arrange
            IRepository<PlatnosciEcard> repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());
            PlatnosciEcard payment = _testDataHelper.CreateNewPayment(_orderNumber, false, _data, 1);
            repPayment.Insert(payment);

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

            var paymentAfterUpdate = repPayment.FindOne(_orderNumber);

            //Assert
            System.Diagnostics.Debug.WriteLine("Status musi byc 'true'. Jest " + paymentAfterUpdate.Status);
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(true));
        }

        [Test]
        [Category("Unit")]
        public void Update_Status_Payment_Is_Not_Update_When_Currentstate_Is_CODE_BAD()
        {
            //Arrange
            IRepository<PlatnosciEcard> repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());
            var payment= _testDataHelper.CreateNewPayment(_orderNumber, false, _data, 1);
            repPayment.Insert(payment);

            var controller = new PlatnoscController(null, repPayment, null, _translateManager);
            
            //Act
            controller.UpdateStatus(_orderNumber, CODE_BAD);
            var paymentAfterUpdate = repPayment.FindOne(i => i.ORDERNUMBER == _orderNumber);

            //Assert
            System.Diagnostics.Debug.WriteLine("Status musi byc 'false'. Jest " + paymentAfterUpdate.Status);
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(false));
        } 
       
        [Test]
        [Category("Unit")]
        public void Show_Action_Returns_Error_View_When_Passing_Incorrect_User_Identity()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "", 0, 0);
            repVPayment.Insert(invoice);

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

            //Assert
            Assert.That(error.Error, Is.EqualTo("weryfikacja"));
            Assert.That(result.ViewName, Is.EqualTo("Error1"));
        }

        [Test]
        [Category("Unit")]
        public void Show_Action_Returns_Error_View_When_Payment_Is_Not_Found()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip2", "", 0, 0);
            repVPayment.Insert(invoice);

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

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


            //Assert
            Assert.That(error.Error, Is.EqualTo("brakdanych"));
            Assert.That(result.ViewName, Is.EqualTo("Error1"));
        }

        [Test]
        [Category("Unit")]
        public void Show_Action_Returns_Paid_View_When_Payment_Is_Paid()
        {
            //Arrange
            //Tworzymy takie dane aby platnosc o danym id byla juz zaplacona 
            var repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "aaa", 0, 0);
            repVPayment.Insert(invoice);
            repVPayment.SubmitChanges();

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

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

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

            //Assert
            Assert.That(result.ViewName, Is.EqualTo("Paid"));
            Assert.That(view.Info, Is.EqualTo("zaplacono"));
        }

        [Test]
        [Category("Unit")]
        public void Show_Action_Returns_View_For_Payment_When_Payment_is_Outstanding()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(invoice);

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

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

            //Act
            var result = controller.Show("123", "pl") as ViewResult;                      
            var view = (InvoiceDetailsViewData)result.ViewData.Model;
            System.Diagnostics.Debug.WriteLine("Brutto 200: " + view.Invoice.Brutto);
            System.Diagnostics.Debug.WriteLine("Nr Faktury musi byc 'numer'. Jest " + view.Invoice.Faktura_Numer);
            
            //Assert
            Assert.That(view.Invoice.Brutto, Is.EqualTo(200));
            Assert.That(view.Invoice.Faktura_Numer, Is.EqualTo("numer"));            
        }

        [Test]
        [Category("Unit")]
        public void AfterPay_Show_Action_Returns_Error_When_Name_Is_Null()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(invoice);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            controller.ControllerContext = _testDataHelper.CreateControllerContext("nip1");
            
            Payer payer = _testDataHelper.CreatePayer(123, "", "test");  //Brak imienia

            //Act
            controller.Show(payer, "pl");

            //Assert
            Assert.That(controller.ModelState.IsValid, Is.False);
        }

        [Test]
        [Category("Unit")]
        public void AfterPay_Show_Action_Returns_Error_When_Surname_Is_Null()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(invoice);

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

            Payer payer = _testDataHelper.CreatePayer(123, "test", "");  //Brak nazwiska

            //Act
            controller.Show(payer, "pl");

            //Assert
            Assert.That(controller.ModelState.IsValid, Is.False);
        }

        [Test]
        [Category("Unit")]
        public void AfterPay_Show_Action_Returns_Error_When_Name_Is_Too_Long()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(invoice);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            controller.ControllerContext = _testDataHelper.CreateControllerContext("nip1");
            var firstname = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            var payer = _testDataHelper.CreatePayer(123, firstname, "test");

            //Act
            controller.Show(payer, "pl");

            //Assert
            Assert.That(controller.ModelState.IsValid, Is.False);
        }

        [Test]
        [Category("Unit")]
        public void AfterPay_Show_Action_Returns_Error_When_Surname_Is_Too_Long()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(invoice);

            var controller = new PlatnoscController(repVPayment, null, null, _translateManager);
            controller.ControllerContext = _testDataHelper.CreateControllerContext("nip1");
            var surname = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            var payer = _testDataHelper.CreatePayer(123, "test", surname);

            //Act
            controller.Show(payer, "pl");

            //Assert
            Assert.That(controller.ModelState.IsValid, Is.False);
        }

        [Test]
        [Category("Unit")]
        public void AfterPay_Show_Action_Returns_Error_When_Name_And_Surname_Is_Not_Null()
        {
            //Arrange
            IRepository<Invoice> repVPayment = new Repository<Invoice>(new FakeDataContext());
            var invoice = _testDataHelper.CreateInvoice(123, "nip1", "numer", 200, 0);
            repVPayment.Insert(invoice);

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

            var payer = _testDataHelper.CreatePayer(123, "test", "test");
  
            //Act
            controller.Show(payer, "pl");
            
            //Assert
            System.Diagnostics.Debug.WriteLine("Model powinien byc 'true'. Jest " + controller.ModelState.IsValid);
            Assert.That(controller.ModelState.IsValid, Is.True);
        }        
    }
}