using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.Database.Audit;
using Microsoft.AspNetCore.Mvc;
using Moq;
using NUnit.Framework;

namespace eSuite.API.UnitTests.Controllers.CustomFieldControllerUnitTest;

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

    [Test]
    public async Task CreateCustomField_WithPredifaindGuid_RetunrOK()
    {
        //Arrange
        var guid = new Guid("37c6853a-3ff3-49d2-94b0-d07944f7b53d");
        var createCustomFieldModel = new CreateCustomField
        {
            Guid = guid,
            DefaultValue = "Name",
            Name = "Name"
        };

        //Act
        var res = await _customFieldController.CreateField(createCustomFieldModel);

        //Assert
        _customFieldManagerMock?.Verify(x => x.CreateFieldAsync(It.IsAny<AuditUserDetails>(), It.Is<CreateCustomField>(x => x.Name == "Name" && x.Guid == guid), default));
        Assert.That(res.GetType(), Is.EqualTo(typeof(OkResult)));
    }

    [Test]
    public void CreateCustomField_ExistingGuid_Returns404()
    {
        //Arrange
        const string errorMessage = "Guid error";

        var guid = new Guid("d8554de5-073d-4169-9442-9f71f494dd87");
        var createCustomFieldModel = new CreateCustomField
        {
            Guid = guid,
            DefaultValue = "Name",
            Name = "Name"
        };
        _customFieldManagerMock?.Setup(x => x.CreateFieldAsync(It.IsAny<AuditUserDetails>(), It.Is<CreateCustomField>(x => x.Guid == guid), default)).ThrowsAsync(new ExistsException(errorMessage));

        //Assert
        Assert.ThrowsAsync<ExistsException>(async () =>
        {
            //Act
            var res = await _customFieldController.CreateField(createCustomFieldModel);
        });

    }

    [Test]
    public async Task CreateCustomField_AutoGenGuid_Returns200()
    {
        //Arrange
        var createCustomFieldModel = new CreateCustomField
        {
            Guid = null,
            DefaultValue = "Name",
            Name = "Name",
            FieldType = Core.CustomFields.FieldType.Text
        };

        //Act
        var res = await _customFieldController.CreateField(createCustomFieldModel);

        //Assert
        _customFieldManagerMock?.Verify(x => x.CreateFieldAsync(It.IsAny<AuditUserDetails>(), It.Is<CreateCustomField>(x => x.Guid == null && x.DefaultValue == "Name" && x.Name == "Name"), default));
        Assert.That(res?.GetType(), Is.EqualTo(typeof(OkResult)));
    }

    [Test]
    public void CreateField_NameExists_Return404()
    {
        //Arrange
        const string errorMesage = "Name Exists";

        var createCustomFieldModel = new CreateCustomField
        {
            Guid = null,
            DefaultValue = "Name",
            Name = "Name",
            FieldType = Core.CustomFields.FieldType.Text
        };
        _customFieldManagerMock?.Setup(x => x.CreateFieldAsync(It.IsAny<AuditUserDetails>(), It.Is<CreateCustomField>(x => x.Name == "Name" && x.DefaultValue == "Name"), default)).ThrowsAsync(new ExistsException(errorMesage));

        //Assert
        Assert.ThrowsAsync<ExistsException>(async () =>
        {
            //Act
            var res = await _customFieldController.CreateField(createCustomFieldModel);
        });
    }

    [Test]
    public async Task CreateField_PredefinedGuid_Returns200()
    {
        //Arrange
        var guid = new Guid("09371a16-6094-4e8d-83ca-ef0ac2092a8d");

        var createCustomFieldModel = new CreateCustomField
        {
            Guid = guid,
            DefaultValue = "Name",
            Name = "Name",
            FieldType = Core.CustomFields.FieldType.Text
        };

        //Act
        var res = await _customFieldController.CreateField(createCustomFieldModel);

        //Assert
        _customFieldManagerMock?.Verify(x => x.CreateFieldAsync(It.IsAny<AuditUserDetails>(), It.Is<CreateCustomField>(x => x.Guid == guid && x.Name == "Name"), It.IsAny<CancellationToken>()));
        Assert.That(res?.GetType(), Is.EqualTo(typeof(OkResult)));
    }
}
