using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using eSuite.Core.Miscellaneous;
using Microsoft.AspNetCore.Mvc;
using Moq;
using NUnit.Framework;

namespace eSuite.API.UnitTests.Controllers.CustomFieldControllerUnitTest;

[TestFixture]
public class GetCustomFieldUnitTest : CustomFieldControllerTestBase
{
    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();
    }

    [Test]
    public async Task GetCustomField_ByGuidOnly_ReturnOk()
    {
        //Arrange
        const long id = -1;
        const string email = "test@test.test";
        const string displayName = "Testy McTester";
        var guid = new Guid("96ff68c5-0b1d-4956-9464-8af65ef1d7ea");

        AddAuthorisedUserToController(id, email, displayName);
        var idRef = new GeneralIdRef
        {
            Guid = guid,
            Id = null
        };

        //Act
        var res = await _customFieldController.GetField(idRef);

        //Assert
        _customFieldManagerMock?.Verify(x => x.GetFieldAsync(It.Is<GeneralIdRef>(x => x.Guid == guid), default), Times.Once());
        Assert.That(res, Is.Not.Null);
        Assert.That(res?.GetType(), Is.EqualTo(typeof(OkObjectResult)));
    }

    [Test]
    public async Task GetCustomField_ByOnlyId_ReturnsOk()
    {
        //Arrange
        const long id = -1;
        const string email = "test@test.test";
        const string displayName = "Testy McTester";
        var idNum = 5;

        AddAuthorisedUserToController(id, email, displayName);
        var idRef = new GeneralIdRef
        {
            Guid = null,
            Id = idNum
        };

        //Act
        var res = await _customFieldController.GetField(idRef);

        //Assert
        _customFieldManagerMock?.Verify(x => x.GetFieldAsync(It.Is<GeneralIdRef>(x => x.Id == idNum), default), Times.Once());
        Assert.That(res, Is.Not.Null);
        Assert.That(res?.GetType(), Is.EqualTo(typeof(OkObjectResult)));
    }

    [Test]
    public async Task GetCustomfield_NormalConditionsByOnlyIdNum_ReturnsRightObj()
    {
        //Arrange
        const long id = -1;
        const string email = "test@test.test";
        const string displayName = "Testy McTester";
        var idNum = 5;
        var guid = new Guid("0d7c1b5b-d322-4ed2-aced-657c9ae3fd96");

        AddAuthorisedUserToController(id, email, displayName);
        var idRef = new GeneralIdRef
        {
            Guid = null,
            Id = idNum
        };
        var objRes = new CustomFieldDefinition
        {
            DefaultValue = "Default",
            FieldType = Core.CustomFields.FieldType.Text,
            Guid = guid,
            Name = "Name"
        };

        _customFieldManagerMock?.Setup(x => x.GetFieldAsync(It.Is<GeneralIdRef>(x => x.Id == idNum), default)).ReturnsAsync(objRes);

        //Act
        var res = await _customFieldController.GetField(idRef);

        //Assert
        Assert.That(res?.GetType(), Is.EqualTo(typeof(OkObjectResult)));
        var objectResult = res as OkObjectResult;
        Assert.That(objectResult?.Value, Is.Not.Null);
        if (objectResult?.Value != null)
        {
            Assert.That(objectResult.Value.GetType(), Is.EqualTo(typeof(CustomFieldDefinition)));
            var field = objectResult?.Value as CustomFieldDefinition;
            Assert.That(field?.Name, Is.EqualTo("Name"));
            Assert.That(field?.Guid, Is.EqualTo(guid));
        }
    }

    [Test]
    public async Task GetCustomField_NormalConditionByOnlyGuidId_ReturnsRightObj()
    {
        //Arrange
        const long id = -1;
        const string email = "test@test.test";
        const string displayName = "Testy McTester";
        var guid = new Guid("5e2964ef-07d7-4e5e-b57d-4fc82d1c4e67");

        AddAuthorisedUserToController(id, email, displayName);
        var idRef = new GeneralIdRef
        {
            Guid = guid,
            Id = null
        };
        var objRes = new CustomFieldDefinition
        {
            DefaultValue = "Default",
            FieldType = Core.CustomFields.FieldType.Text,
            Guid = guid,
            Name = "Name"
        };

        _customFieldManagerMock?.Setup(x => x.GetFieldAsync(It.Is<GeneralIdRef>(x => x.Guid == guid), default)).ReturnsAsync(objRes);

        //Act
        var res = await _customFieldController.GetField(idRef);

        //Assert
        Assert.That(res?.GetType(), Is.EqualTo(typeof(OkObjectResult)));
        var objectResult = res as OkObjectResult;
        Assert.That(objectResult?.Value, Is.Not.Null);
        if (objectResult?.Value != null)
        {
            Assert.That(objectResult.Value.GetType(), Is.EqualTo(typeof(CustomFieldDefinition)));
            var field = objectResult?.Value as CustomFieldDefinition;
            Assert.That(field?.Name, Is.EqualTo("Name"));
        }
    }

    [Test]
    public void GetCustomField_FieldIdNotFound_Retruns404()
    {
        //Arrange
        const long id = -1;
        const string email = "test@test.test";
        const string displayName = "Testy McTester";
        const string notFound = "field not found error";
        var guid = new Guid("e89d2a53-313e-4221-be0d-1df72b839d77");

        AddAuthorisedUserToController(id, email, displayName);
        var idRef = new GeneralIdRef
        {
            Guid = null,
            Id = null
        };
        _customFieldManagerMock?.Setup(x => x.GetFieldAsync(It.Is<GeneralIdRef>(x => x.Id == null && x.Guid == null), default)).ThrowsAsync(new NotFoundException(notFound));

        //Assert
        Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            //Act
            var res = await _customFieldController.GetField(idRef);
        });
    }

}
