﻿using System;
using System.Collections.Specialized;
using System.Linq;
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 NUnit.Framework;
using MvcContrib.TestHelper;
using System.Web.Mvc;

namespace adMoto.Payments.Test.Controllers
{
    [TestFixture]
// ReSharper disable InconsistentNaming
    public class eCardControllerTests
// ReSharper restore InconsistentNaming
    {
        private readonly TestDataHelper _testDataHelper = new TestDataHelper();
        private IRepository<PotwierdzeniaEcard> _repConfirm;
       // private IRepository<PlatnosciEcard> _repPayment;
        private const string CODE_OK = "payment_deposited";        //transakcja potwierdzona do rozliczenia
        private const string CODE_BAD = "payment_declined";        //transakcja odrzucona 
        
        private eCardController CreateController()
        {
            _repConfirm = new Repository<PotwierdzeniaEcard>(new FakeDataContext());

            var builder = new TestControllerBuilder();
            return builder.CreateController<eCardController>(_repConfirm); 
        }

        [Test]
        [Category("Unit")]
        public void  Status_Returns_True_When_Passing_Correct_Request_Data()
        {
            var controller = CreateController();
            const string dateFormat = "yyyy-MM-dd HH:mm:ss.fff";
            var dateTime = DateTime.Now.ToString(dateFormat);
            var formValues = new NameValueCollection {
                                                         {"MERCHANTNUMBER", "1"}, 
                                                         {"ORDERNUMBER", "2"},
                                                         {"COMMTYPE", "3"},
                                                         {"CURRENTSTATE", "4"},
                                                         {"PREVIOUSSTATE", "5"},
                                                         {"PAYMENTTYPE", "1"},
                                                         {"EVENTTYPE", "0"},
                                                         {"PAYMENTNUMBER", "1"},
                                                         {"APPROVALCODE", "6"},
                                                         {"VALIDATIONCODE", "7"},
                                                         {"BIN", "8"},
                                                         {"AUTHTIME", dateTime},
                                                         {"TYPE", "9"},
                                                         {"WITHCVC", "10"}};
            controller.Request.Form.Add(formValues);

            var result = controller.Status() as ContentResult;

            Assert.That(result.Content.Contains("OK"));
            
            var paymentConfirmation = _repConfirm.FindAll().First();
            Assert.That(paymentConfirmation.MERCHANTNUMBER, Is.EqualTo("1"));
            Assert.That(paymentConfirmation.ORDERNUMBER, Is.EqualTo(2));
            Assert.That(paymentConfirmation.COMMTYPE, Is.EqualTo("3"));
            Assert.That(paymentConfirmation.CURRENTSTATE, Is.EqualTo("4"));
            Assert.That(paymentConfirmation.PREVIOUSSTATE, Is.EqualTo("5"));
            Assert.That(paymentConfirmation.APPROVALCODE, Is.EqualTo("6"));
            Assert.That(paymentConfirmation.VALIDATIONCODE, Is.EqualTo("7"));
            Assert.That(paymentConfirmation.BIN, Is.EqualTo("8"));
            Assert.That(paymentConfirmation.TYPE, Is.EqualTo("9"));
            Assert.That(paymentConfirmation.WITHCVC, Is.EqualTo("10"));
            Assert.That(paymentConfirmation.PAYMENTTYPE, Is.True);
            Assert.That(paymentConfirmation.EVENTTYPE, Is.False);
            Assert.That(paymentConfirmation.PAYMENTNUMBER, Is.True);
            Assert.That(paymentConfirmation.AUTHTIME.Value.ToString(dateFormat), Is.EqualTo(dateTime));
        }

        [Test]
        [Category("Unit")]
        public void Status_Returns_False_And_Throws_FormatException_When_Passing_OrderNumber_In_Wrong_Format()
        {
            var controller = CreateController();
            var valueCollection = new NameValueCollection {{"ORDERNUMBER", "fdsf"}};
            controller.Request.Form.Add(valueCollection);

            var result = controller.Status() as ContentResult;

            Assert.That(_repConfirm.Count(), Is.EqualTo(0));
            Assert.That(result.Content.Contains("FALSE"));
            Assert.That(result.Content.Contains("FormatException"));
        }

        [Test]
        [Category("Unit")]
        public void Status_Returns_False_And_Throws_FormatException_When_Passing_PaymentType_In_Wrong_Format()
        {
            var controller = CreateController();
            var valueCollection = new NameValueCollection { { "PAYMENTTYPE", "32hvhsvhv" } };
            controller.Request.Form.Add(valueCollection);

            var result = controller.Status() as ContentResult;

            Assert.That(_repConfirm.Count(), Is.EqualTo(0));
            Assert.That(result.Content.Contains("FALSE"));
            Assert.That(result.Content.Contains("FormatException"));
        }

        [Test]
        [Category("Unit")]
        public void Status_Returns_False_And_Throws_FormatException_When_Passing_EventType_In_Wrong_Format()
        {
            var controller = CreateController();
            var valueCollection = new NameValueCollection { { "EVENTTYPE", "32hvhsvhv" } };
            controller.Request.Form.Add(valueCollection);

            var result = controller.Status() as ContentResult;

            Assert.That(_repConfirm.Count(), Is.EqualTo(0));
            Assert.That(result.Content.Contains("FALSE"));
            Assert.That(result.Content.Contains("FormatException"));
        }

        [Test]
        [Category("Unit")]
        public void Status_Returns_False_And_Throws_OverflowException_When_Passing_OrderNumer_Greater_Than_Integer()
        {
            var controller = CreateController();
            var valueCollection = new NameValueCollection { { "ORDERNUMBER", "12311111111111111" } };
            controller.Request.Form.Add(valueCollection);

            var result = controller.Status() as ContentResult;

            Assert.That(_repConfirm.Count(), Is.EqualTo(0));
            Assert.That(result.Content.Contains("FALSE"), "Response should contain FALSE");
            Assert.That(result.Content.Contains("OverflowException"), "Response should contain OverflowException");
        }

        [Test]
        [Category("Unit")]
        public void Status_Returns_False_And_Throws_SqlException_When_Passing_ValidationCode_Longer_Than_Three_Characters()
        {
            var controller = CreateController();
            var valueCollection = new NameValueCollection { { "VALIDATIONCODE", "1234" } };
            controller.Request.Form.Add(valueCollection);

            var result = controller.Status() as ContentResult;

            Assert.That(_repConfirm.Count(), Is.EqualTo(0), "Should not have any items");
            Assert.That(result.Content.Contains("FALSE"), "Response should contain FALSE");
            Assert.That(result.Content.Contains("ArgumentException"), "Response should contain SqlException");
        }

        /*[Test]
        [Category("Unit")]
        public void Status_Action_Saves_Correct_Transaction()
        {  
            //Arrange 
            _repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());
            var payment = _testDataHelper.CreateNewPayment(2, false, DateTime.Now, 12345);
            _repPayment.Insert(payment);
            _repPayment.SubmitChanges();

            var controller = CreateController();
            var valueCollection = new NameValueCollection {
                                                         {"MERCHANTNUMBER", "1"}, 
                                                         {"ORDERNUMBER", "2"},
                                                         {"AUTHTIME", DateTime.Now.ToString()},
                                                         {"CURRENTSTATE", CODE_OK}};
            controller.Request.Form.Add(valueCollection);

            //Act
            controller.Status();           
            var confirm = _repConfirm.Find(o => o.ORDERNUMBER == 2).SingleOrDefault();

            //Assert
            Assert.That(confirm.MERCHANTNUMBER, Is.EqualTo("1"));

            //Act
            var paymentAfterUpdate = _repPayment.FindOne(2);   
            System.Diagnostics.Debug.WriteLine("Status musi byc 'true'. Jest " + paymentAfterUpdate.Status);

            //Assert
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(true));            
        }*/
        /*[Test]
        [Category("Unit")]
        public void Status_Action_Payment_Is_Not_Update_When_Currentstate_Is_CODE_BAD()
        {  
            //Arrange 
            _repPayment = new Repository<PlatnosciEcard>(new FakeDataContext());
            var payment = _testDataHelper.CreateNewPayment(2, false, DateTime.Now, 12345);
            _repPayment.Insert(payment);
            _repPayment.SubmitChanges();

            var controller = CreateController();
            var valueCollection = new NameValueCollection {
                                                         {"MERCHANTNUMBER", "1"}, 
                                                         {"ORDERNUMBER", "2"},
                                                         {"AUTHTIME", DateTime.Now.ToString()},
                                                         {"CURRENTSTATE", CODE_BAD}};
            controller.Request.Form.Add(valueCollection);

            //Act
            controller.Status();           
            var confirm = _repConfirm.Find(o => o.ORDERNUMBER == 2).SingleOrDefault();

            //Assert
            Assert.That(confirm.MERCHANTNUMBER, Is.EqualTo("1"));

            //Act
            var paymentAfterUpdate = _repPayment.FindOne(2);   
            System.Diagnostics.Debug.WriteLine("Status musi byc 'false'. Jest " + paymentAfterUpdate.Status);

            //Assert
            Assert.That(paymentAfterUpdate.Status, Is.EqualTo(true));            
        }*/

       }
}