﻿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 int orderNumber = 9999;
        private string code_Ok = "payment_deposited";        //transakcja potwierdzona do rozliczenia
        private string code_Bad = "payment_declined";        //transakcja odrzucona 
        private DateTime data = DateTime.Now;
        private string testNip1 = "12345";
        private string testNip2 = "01234";
        private int testIdFaktury = 1000;
        private string testNumerFaktury = "abcd";
        private decimal testBrutto = 200;
        private int test = 1; //oznacza, ze nie ustawiamy tlumaczen poprzez funkcje ustawTlumaczenia()
                              //w controllerze Platnosci, tylko poprzez funkcje setXXXXXXX()

        private Function _f = new Function();
        private FunkcjePlatnosci _func = new FunkcjePlatnosci();
        
        [Test]
        [Category("Unit")]
        public void Status_Saves_Correct_Transaction()
        {          
           // //IDataContext fake = new FakeDataContext();
           // var repository = new Repository<PlatnosciEcard>(new FakeDataContext());
           // var platnosci = _f.createNewPayment(orderNumber, false, DateTime.Now, 12345); //new PlatnosciEcard();
           // repository.Insert(platnosci);
           // repository.SubmitChanges();


           // DateTime datka = DateTime.Now;
           // var builder = new TestControllerBuilder();
           // var controller = new PlatnoscController(fake,test);
           // 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());
           // builder.Form.Add("CURRENTSTATE", code_Ok);           
           
           // var result = controller.Status();
           
           // IRepository<PotwierdzeniaEcard> _rep = new Repository<PotwierdzeniaEcard>(new FakeDataContext());


           // System.Diagnostics.Debug.WriteLine("" + _rep.Count());

           // //var potwierdzeniaEcard = _rep.Find(p => p.ORDERNUMBER == orderNumber).First();
           //// Assert.That(potwierdzeniaEcard.MERCHANTNUMBER, Is.EqualTo(merchantNumber));
           // PlatnosciEcard payment_after_update = _rep.FindPaymentByOrdernumber(orderNumber).SingleOrDefault();
           // System.Diagnostics.Debug.WriteLine(payment_after_update.Status_data + " > " + datka);
           // Assert.That(payment_after_update.Status, Is.EqualTo(true));
            
        }
        [Test]
        [Category("Unit")]
        public void Status_Saves_Correct_Transaction_IncorrectUpdate()
        {
            FakeDataContext fake = new FakeDataContext(2);
            DateTime datka = DateTime.Now;
            var builder = new TestControllerBuilder();
            var controller = new PlatnoscController(fake,test);
            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());
            builder.Form.Add("CURRENTSTATE", code_Bad);

            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));

            
            PlatnosciEcard payment_after_update = _rep.FindPaymentByOrdernumber(orderNumber).SingleOrDefault();
            System.Diagnostics.Debug.WriteLine(payment_after_update.Status_data + " <= " + datka );
            Assert.That(payment_after_update.Status_data, Is.LessThanOrEqualTo(datka));
        }
        [Test]
        [Category("Unit")]
        public void StatusIsUpdated()
        {
            FakeDataContext fake = new FakeDataContext(3);
            IRepository<PlatnosciEcard> _rep = new Repository<PlatnosciEcard>(fake);

            PlatnosciEcard platnosc = _f.createNewPayment(orderNumber, false, data.AddDays(-1), 1);
            _rep.Insert(platnosc);

            DateTime datka = DateTime.Now;
            var controller = new PlatnoscController(fake,test);
            controller.UpdateStatus(orderNumber, code_Ok);   
            
            PlatnosciEcard payment_after_update = new PlatnosciEcard();
            payment_after_update = _rep.FindOne(orderNumber);
            
            Assert.That(payment_after_update.Status, Is.EqualTo(true));
        }
        [Test]
        [Category("Unit")]
        public void StatusIsNotUpdated()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<PlatnosciEcard> _rep = new Repository<PlatnosciEcard>(fake);

            PlatnosciEcard platnosc = _f.createNewPayment(orderNumber, true, data, 1);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake,test);
            controller.UpdateStatus(orderNumber, code_Bad);   

            PlatnosciEcard payment_after_update = new PlatnosciEcard();
            payment_after_update = _rep.FindOne(i => i.ORDERNUMBER == orderNumber);
            Assert.That(payment_after_update.Status_data, Is.EqualTo(data));
        }        
        [Test]
        [Category("Unit")]
        public void ActionShowPayment_IncorrectUserIdentity_ReturnErrorView()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = _f.createPayment(testIdFaktury, testNip1, testNumerFaktury, 0, 0);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake,test);
            controller.ControllerContext = _f.createControllerContext(testNip2);
            controller.setWeryfikacja("Niepoprawny nip");            
           
            var result = controller.Show(testIdFaktury.ToString(),"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);

            var controller = new PlatnoscController(fake,test);

            controller.ControllerContext = _f.createControllerContext(testNip1);
            controller.setBrakDanych("Platnosc o takim id nie istnieje");

            var result = controller.Show(testIdFaktury.ToString(), "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_PaymentIsPaid(){
            //Tworzymy takie dane aby platnosc o danym id byla juz zaplacona 
            FakeDataContext fake = new FakeDataContext(1); 
            var controller = new PlatnoscController(fake,test);

            controller.ControllerContext = _f.createControllerContext(testNip1);
            controller.setZaplacono("Platnosc zostala uregulowana");

            var result = controller.Show(testIdFaktury.ToString(), "pl") as ViewResult;
            var view = (InvoiceDetailsViewData)result.ViewData.Model;

            Assert.That(result.ViewName, Is.EqualTo("Paid"));
            Assert.That(view.info, 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 = _f.createPayment(testIdFaktury, testNip1, testNumerFaktury, testBrutto, 0);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake,test);
            controller.ControllerContext = _f.createControllerContext(testNip1);

            var result = controller.Show(testIdFaktury.ToString(), "pl") as ViewResult;
            Assert.IsInstanceOfType(typeof(InvoiceDetailsViewData), result.ViewData.Model);
            
            var view = (InvoiceDetailsViewData)result.ViewData.Model;
            Assert.That(view.vPlatnosciEcard.Brutto, Is.EqualTo(testBrutto));
            Assert.That(view.vPlatnosciEcard.Faktura_Numer, Is.EqualTo(testNumerFaktury));            
        }
        [Test]
        [Category("Unit")]
        public void AfterPay_PaymentIsNotValid()
        {
            FakeDataContext fake = new FakeDataContext();
            IRepository<vPlatnosciEcard> _rep = new Repository<vPlatnosciEcard>(fake);

            vPlatnosciEcard platnosc = _f.createPayment(testIdFaktury, testNip1, testNumerFaktury, testBrutto, 2);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake,1);
            controller.ControllerContext = _f.createControllerContext(testNip1);
            
            Payer payer = _f.createPayer(testIdFaktury, "", "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 = _f.createPayment(testIdFaktury, testNip1, testNumerFaktury, testBrutto, 2);
            _rep.Insert(platnosc);

            var controller = new PlatnoscController(fake,test);
            controller.ControllerContext = _f.createControllerContext(testNip1);

            Payer payer = _f.createPayer(testIdFaktury, "test", "test");  
            var result = controller.Show(payer, "pl") as ViewResult;

            System.Diagnostics.Debug.WriteLine("AfterPay_PaymentIsValid_Test");
            Assert.That(controller.ModelState.IsValid, Is.True, "Model powinien byc true");
        }
    }
}

