using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

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

using Platnosci.Core.Interface;
using Platnosci.Core.Linq;
using WatiN.Core;
using System.Threading;
using Platnosci.Models;
using Moq;

namespace Platnosci.Tests.Web
{
    [TestFixture]
   
    class PlatnosciControllerTests
    {
        private string merchantNumber = "123";
        private FunkcjePlatnosci _func = new FunkcjePlatnosci();

         /*[TearDown]
         public void TearDown()
         {
             IRepository<PotwierdzeniaEcard> _rep = new Repository<PotwierdzeniaEcard>();
             var potwierdzeniaEcard = _rep.Find(p => p.MERCHANTNUMBER == merchantNumber);

             foreach (var pe in potwierdzeniaEcard)
             {
                 _rep.Delete(pe);
             }
         }
        */

        public vPlatnosciEcard createPayment(int id, string nip, string fak_numer, decimal brutto, byte SystemKsiegowy)
        {

            vPlatnosciEcard platnosc = new vPlatnosciEcard();
            platnosc.ID_faktury = id;
            platnosc.nip = nip;
            platnosc.Faktura_Numer = fak_numer;
            platnosc.Brutto = brutto;
            platnosc.SystemKsiegowyId = SystemKsiegowy;

            return platnosc;
        }
        public PlatnosciEcard createNewPayment(int ordernumber, bool status, DateTime data, int id_faktury)
        {
            PlatnosciEcard platnosc = new PlatnosciEcard();
            platnosc.ORDERNUMBER = ordernumber;
            platnosc.Status = status;
            platnosc.Status_data = data;
            platnosc.IDFaktury = id_faktury;

            return platnosc;
        }
        public Payer createPayer(int id, string name, string surname)
        {
            Payer payer = new Payer();
            payer.Id_faktury = id;
            payer.FirstName = name;
            payer.LastName = surname;

            return payer;
        }
        public ControllerContext createControllerContext(string UserIdentity)
        {

            var mock = new Mock<ControllerContext>();
            mock.SetupGet(m => m.HttpContext.User.Identity.Name).Returns(UserIdentity);
            mock.SetupGet(m => m.HttpContext.Request.IsAuthenticated).Returns(true);

            return mock.Object;
        }
        [Test]
        [Category("Unit")]
        public void Status_Saves_Correct_Transaction()
        {          
            var orderNumber = 9999;
            FakeDataContext fake = new FakeDataContext();
            var builder = new TestControllerBuilder();
            var controller = new PlatnoscController(fake);
            builder.InitializeController(controller);
            builder.Form.Add("MERCHANTNUMBER", merchantNumber.ToString());
            builder.Form.Add("AUTHTIME", DateTime.Now.ToString());
            builder.Form.Add("DATATRANSMISJI", DateTime.Now.ToString());
            builder.Form.Add("ORDERNUMBER", orderNumber.ToString());

            var result = controller.Status();

            IRepository<PotwierdzeniaEcard> _rep = new Repository<PotwierdzeniaEcard>(fake);            
            var potwierdzeniaEcard = _rep.Find(p => p.ORDERNUMBER == orderNumber).First();
            Assert.That(potwierdzeniaEcard.MERCHANTNUMBER, Is.EqualTo(merchantNumber));            
        }
        [Test]
        [Category("Unit")]
        public void StatusIsUpdated()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<PlatnosciEcard> _rep = new Repository<PlatnosciEcard>(fake);

            DateTime data = DateTime.Now;
            PlatnosciEcard platnosc = createNewPayment(1, true, data, 1);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake); 
            controller.UpdateStatus(1, "000");   //000 - płatność poprawna

            PlatnosciEcard payment_after_update = new PlatnosciEcard();
            payment_after_update = _rep.FindOne(i => i.ORDERNUMBER == 1);
            Assert.That(payment_after_update.Status_data, Is.GreaterThan(data));
        }
        [Test]
        [Category("Unit")]
        public void StatusIsNotUpdated()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<PlatnosciEcard> _rep = new Repository<PlatnosciEcard>(fake);

            DateTime data = DateTime.Now;

            PlatnosciEcard platnosc = createNewPayment(1, true, data, 1);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake);
            controller.UpdateStatus(1, "111");   //111 - płatność niepoprawna, ze wzgledu na zly numer karty

            PlatnosciEcard payment_after_update = new PlatnosciEcard();
            payment_after_update = _rep.FindOne(i => i.ORDERNUMBER == 1);
            Assert.That(payment_after_update.Status_data, Is.EqualTo(data));
        }        
        [Test]
        [Category("Unit")]
        public void TestFindInvoiceByNumber()
        {
             FakeDataContext fake = new FakeDataContext();
             IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

             vPlatnosciEcard platnosc = new vPlatnosciEcard();
             platnosc = _rep.FindInvoiceById(1).SingleOrDefault();
             Assert.That(platnosc.Faktura_Numer, Is.EqualTo("1"));
        }
        [Test]
        [Category("Unit")]
        public void TestInsertMethodForPayment()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = createPayment(13, "nipek", "", 0, 0);
            _rep.Insert(platnosc);

            vPlatnosciEcard pl1 = createPayment(14, "vv", "", 0, 0);
            _rep.Insert(pl1);

            vPlatnosciEcard pl = _rep.FindInvoiceById(13).SingleOrDefault();
            Assert.That(pl.nip, Is.EqualTo("nipek"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_IncorrectUserIdentity_ReturnErrorView()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = createPayment(74828, "854956281", "27/ASZ/2009", 0, 0);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake);
            controller.ControllerContext = createControllerContext("1");
            controller.setWeryfikacja("Niepoprawny nip");
            
           
            var result = controller.Show("74828","pl") as ViewResult;
            var error = (ErrorViewData)result.ViewData.Model;
            
            Assert.That(error.error, Is.EqualTo("Niepoprawny nip"));
            Assert.That(result.ViewName, Is.EqualTo("Error1"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_PaymentNotFound_ReturnErrorView()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = createPayment(74828, "854956281", "27/ASZ/2009", 0,0);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake);

            controller.ControllerContext = createControllerContext("854956281");
            controller.setBrakDanych("Platnosc o takim id nie istnieje");

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

            Assert.That(error.error, Is.EqualTo("Platnosc o takim id nie istnieje"));
            Assert.That(result.ViewName, Is.EqualTo("Error1"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_PaymentIsPayed(){
            //Tworzymy takie dane aby platnosc o danym id byla juz zaplacona 
            FakeDataContext fake = new FakeDataContext(1); 
            var controller = new PlatnoscController(fake);

            controller.ControllerContext = createControllerContext("nip");
            controller.setZaplacono("Platnosc zostala uregulowana");

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

            Assert.That(result.ViewName, Is.EqualTo("Error1"));
            Assert.That(error.error, Is.EqualTo("Platnosc zostala uregulowana"));
        }
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_CorrectData_ReturnViewForPayment()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);
                                                  
            vPlatnosciEcard platnosc = createPayment(74828,"854956281","27/ASZ/2009",200,0);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake);
            controller.ControllerContext = createControllerContext("854956281");

            var result = controller.Show("74828", "pl") as ViewResult;
            Assert.IsInstanceOfType(typeof(InvoiceDetailsViewData), result.ViewData.Model);
            
            var view = (InvoiceDetailsViewData)result.ViewData.Model;
            Assert.That(view.vPlatnosciEcard.Brutto, Is.EqualTo(200));
            Assert.That(view.vPlatnosciEcard.Faktura_Numer, Is.EqualTo("27/ASZ/2009"));            
        }
        [Test]
        [Category("Unit")]
        public void AfterPay_PaymentIsNotValid()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = createPayment(74828, "854956281", "27/ASZ/2009", 200, 2);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake);
            controller.ControllerContext = createControllerContext("854956281");
            
            Payer payer = createPayer(74828, "", "test");  //Brak imienia
            controller.Show(payer, "pl");

            Assert.That(controller.ModelState.IsValid, Is.False);
        }
        [Test]
        [Category("Unit")]
        public void AfterPay_PaymentIsValid()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = createPayment(74828, "854956281", "27/ASZ/2009", 200, 2);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake);
            controller.ControllerContext = createControllerContext("854956281");

            Payer payer = createPayer(74828, "test", "test");  
            controller.Show(payer, "pl");

            Assert.That(controller.ModelState.IsValid, Is.True); 
        }        
        [Test]
        [Category("UI")]
        public void checkLoginCorrect()
        {
            IE ie = new IE("http://localhost:3646/pl/Account/LogOn");
            ie.TextField(Find.ByName("numer_faktury")).TypeText("24/HOL/2009");
            ie.TextField(Find.ByName("nip")).TypeText("501379568");
            ie.Button(Find.ById("but")).Click();
            Assert.IsTrue(ie.ContainsText("została uregulowana"));
        }
        [Test]
        [Category("UI")]
        public void checkErrorLogin()
        {
            IE ie = new IE("http://localhost:3646/pl/Account/LogOn");
            ie.TextField(Find.ByName("numer_faktury")).TypeText("");
            ie.TextField(Find.ByName("nip")).TypeText("");
            ie.Button(Find.ById("but")).Click();
            Assert.IsTrue(ie.ContainsText("Logowanie nie powiodło się"));
        }
      
    }
}

