using System.ComponentModel.DataAnnotations;
using e_suite.API.Common;
using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.API.Common.repository;
using e_suite.Database.Audit;
using e_suite.Database.Core.Tables.CustomFields;
using e_suite.Database.Core.Tables.Domain;
using e_suite.Database.Core.Tables.Forms;
using e_suite.Database.Core.Tables.Glossaries;
using e_suite.Service.CustomFieldValidation;
using e_suite.UnitTestCore;
using eSuite.Core.CustomFields;
using eSuite.Core.Miscellaneous;
using Moq;
using NUnit.Framework;

namespace e_suite.Service.CustomFieldValidationUnitTests;

[TestFixture]
public class CustomFieldValidatorUnitTests : TestBase
{
    private Mock<ICustomFieldValidatorRepository> _customFieldValidatorRepositoryMock = null!;
    private Mock<ISequenceManager> _sequenceManagerMock = null!;

    private CustomFieldValidator _customFieldValidator = null!;

    private AuditUserDetails _auditUserDetails = null!;

    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();

        _auditUserDetails = new()
        {
            UserId = 1,
            UserDisplayName = "Testy McTester",
            Comment = "I'm testing stuff to see if it works"
        };

        _customFieldValidatorRepositoryMock = new();
        _sequenceManagerMock = new();

        _customFieldValidator = new(_customFieldValidatorRepositoryMock.Object, _sequenceManagerMock.Object);
    }

    [Test]
    public async Task ValidateFields_CalledWithEmptyValues_ReturnsNothing()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>();
        var customFields = new List<CustomField>();

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(0));
    }

    [Test]
    public void ValidateFields_CustomFieldsListNull_ThrowsException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>();
        List<CustomField> customFields = null!;

        //Act & Assert

        Assert.ThrowsAsync<ArgumentNullException>(async () =>
        {
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });
    }

    [Test]
    public void ValidateFields_FieldDefinitionNotFound_ThowsExpectedException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values =
                [
                    new ()
                    {
                        Value = "TestValue", DisplayValue = "TestValue"
                    }
                ]
            }
        };

        var customFields = new List<CustomField>();

        //Act & Assert
        Assert.ThrowsAsync<NullReferenceException>(async () =>
        {
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });
    }

    [Test]
    public async Task ValidateFields_FieldDefinitionFound_ThrowsExpectedException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = "TestValue", DisplayValue = "TestValue"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Text,
                DefaultValue = string.Empty
            }
        };

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));

        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("TestValue"));
        Assert.That(result[0].DisplayValue, Is.EqualTo("TestValue"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldContainsDuplicates_ResultsFilterOutDuplicates()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () {Value = "TestValue", DisplayValue = "TestValue"}, new() { Value = "TestValue", DisplayValue = "TestValue" }]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Text,
                DefaultValue = string.Empty
            }
        };

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));

        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("TestValue"));
        Assert.That(result[0].DisplayValue, Is.EqualTo("TestValue"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldContainsValueMissing_DefaultValueIsCreated()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>();

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Text,
                DefaultValue = "DefaultValue"
            }
        };

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));

        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("DefaultValue"));
        Assert.That(result[0].DisplayValue, Is.EqualTo("DefaultValue"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldIsSequence_ValueObtainedFromSequence()
    {
        //Arrange
        var expectedResult = "1";

        var customFieldValues = new List<CustomFieldValues>();

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Sequence,
                DefaultValue = ""
            }
        };

        var sequenceValues = new List<string> { expectedResult };

        _sequenceManagerMock.Setup(x => x.NextValue(It.IsAny<AuditUserDetails>(), It.IsAny<GeneralIdRef>(), It.IsAny<CancellationToken>())).Returns(() => Task.FromResult<IEnumerable<string>>(sequenceValues));

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));

        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo(expectedResult));
        Assert.That(result[0].DisplayValue, Is.EqualTo(expectedResult));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldIsSequenceAndValueAlreadySet_ValueIsNotChanged()
    {
        //Arrange
        var expectedResult = "2";

        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = expectedResult, DisplayValue = "TestValue"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Sequence,
                DefaultValue = ""
            }
        };

        var sequenceValues = new List<string> { "2" };

        _sequenceManagerMock.Setup(x => x.NextValue(It.IsAny<AuditUserDetails>(), It.IsAny<GeneralIdRef>(), It.IsAny<CancellationToken>())).Returns(() => Task.FromResult<IEnumerable<string>>(sequenceValues));

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));

        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo(expectedResult));
        Assert.That(result[0].DisplayValue, Is.EqualTo(expectedResult));
        Assert.That(result[0].Valid, Is.True);
    }
    
    [Test]
    public void ValidateFields_AtLeastOneEntryRequiredAndNotSupplied_ThrowsMinEntryException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>();

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                Name = "TestFieldName",
                FieldType = FieldType.FormTemplate,
                DefaultValue = "",
                MinEntries = 1
            }
        };

        //Act
        var exception = Assert.ThrowsAsync<MinimumRangeException>(async () =>
        {
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });

        //Assert
        Assert.That(exception?.Message, Is.EqualTo($"TestFieldName Requires at least one entry"));
    }

    [Test]
    public void ValidateFields_AtMostOneEntryRequiredAndTwoSupplied_ThrowsMaxEntryException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = "1", DisplayValue = "TestValue1"}, new() { Value = "2", DisplayValue = "TestValue2" }]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                Name = "TestFieldName",
                FieldType = FieldType.Text,
                DefaultValue = "",
                MaxEntries = 1
            }
        };

        //Act
        var exception = Assert.ThrowsAsync<MaximumRangeException>(async () =>
        {
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });

        //Assert
        Assert.That(exception?.Message, Is.EqualTo($"TestFieldName Can have 1 entries at most"));
    }

    [Test]
    public void ValidateFields_FieldIsFormTemplateAndTemplateNotFound_ThrowsException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new()
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = "{\"id\":1}", DisplayValue = "TestValue1"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.FormTemplate,
                DefaultValue = ""
            }
        };

        //Act & Assert
        Assert.ThrowsAsync<NullReferenceException>(async () =>
        {
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });
    }

    [Test]
    public async Task ValidateFields_FieldIsFormTemplateAndTemplateFound_ReturnsExpectedResult()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = "{\"id\":1}", DisplayValue = "TestValue1"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.FormTemplate,
                DefaultValue = ""
            }
        };

        var formTemplate = new FormTemplate
        {
            Id = 1,
            Name = "TestForm",
            Guid = new("5D2D337A-EA31-4805-A580-F148D02E5A10")
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetTemplateByGeneralRefId(It.IsAny<GeneralIdRef>(), It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(formTemplate)!);

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));
        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("5D2D337A-EA31-4805-A580-F148D02E5A10".ToLower()));
        Assert.That(result[0].DisplayValue, Is.EqualTo("TestForm"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public void ValidateFields_FieldIsGlossaryAndItemNotFound_ThrowsException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new()
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = "{\"id\":1}", DisplayValue = "TestValue1"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Glossary,
                DefaultValue = ""
            }
        };

        //Act & Assert
        Assert.ThrowsAsync<NullReferenceException>(async () =>
        {
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });
    }

    [Test]
    public async Task ValidateFields_FieldIsGlossaryAndItemFound_ReturnsExpectedResult()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("{5814570A-7830-4160-9F64-5596A83616EC}")
                },
                Values = [new () { Value = "{\"id\":1}", DisplayValue = "TestValue1"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("{5814570A-7830-4160-9F64-5596A83616EC}"),
                FieldType = FieldType.Glossary,
                DefaultValue = ""
            }
        };

        var formTemplate = new Glossary
        {
            Id = 1,
            Name = "TestGlossary",
            Guid = new("2f28ac0a-d681-4ac1-82ff-aa423ca0e8fe")
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetGlossaryByGeneralRefId(It.IsAny<GeneralIdRef>(), It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(formTemplate)!);

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));
        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("2f28ac0a-d681-4ac1-82ff-aa423ca0e8fe"));
        Assert.That(result[0].DisplayValue, Is.EqualTo("TestGlossary"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldIsDomainAndItemFound_ReturnsExpectedResult()
    {
        //Arrange
        var customFieldGuid = new Guid("1a0bb5ad-201c-49d5-91f6-6b2326418525");
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = customFieldGuid
                },
                Values = [new () { Value = "{\"id\":1}", DisplayValue = "TestValue1"}]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = customFieldGuid,
                FieldType = FieldType.Domain,
                DefaultValue = ""
            }
        };

        var formTemplate = new Domain
        {
            Id = 1,
            Name = "Test domain",
            Guid = new("c3856531-cb23-4559-9cb4-5d600c8ab457")
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetDomainByGeneralRefId(It.IsAny<GeneralIdRef>(), It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(formTemplate)!);

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));
        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("c3856531-cb23-4559-9cb4-5d600c8ab457"));
        Assert.That(result[0].DisplayValue, Is.EqualTo("Test domain"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldIsDomainGeneralIdRefAndItemFound_ReturnsExpectedResult()
    {
        //Arrange
        var customFieldGuid = new Guid("1a0bb5ad-201c-49d5-91f6-6b2326418525");
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = customFieldGuid
                },
                Values =
                [
                    new()
                    {
                        Value = new GeneralIdRef
                        {
                            Id = 1
                        }

                    }
                ]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = customFieldGuid,
                FieldType = FieldType.Domain,
                DefaultValue = ""
            }
        };

        var formTemplate = new Domain
        {
            Id = 1,
            Name = "Test domain",
            Guid = new("c3856531-cb23-4559-9cb4-5d600c8ab457")
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetDomainByGeneralRefId(It.IsAny<GeneralIdRef>(), It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(formTemplate)!);

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));
        Assert.That(result[0].CustomFieldId, Is.EqualTo(1));
        Assert.That(result[0].Index, Is.EqualTo(0));
        Assert.That(result[0].Value, Is.EqualTo("c3856531-cb23-4559-9cb4-5d600c8ab457"));
        Assert.That(result[0].DisplayValue, Is.EqualTo("Test domain"));
        Assert.That(result[0].Valid, Is.True);
    }

    [Test]
    public async Task ValidateFields_FieldIsNumberAndValueIsOptionalAndNoValueSupplied_ReturnsSuccess()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new()
                {
                    Guid = new Guid("abe34ee2-f3cc-4968-b2a9-892bdc15192f")
                },
                Values = [ new CustomFieldValue { Value = ""} ]
            }
        };

        var customFields = new List<CustomField>
        {
            new()
            {
                Id = 1,
                Guid = new("abe34ee2-f3cc-4968-b2a9-892bdc15192f"),
                FieldType = FieldType.Number,
                DefaultValue = "",
                MinEntries = 0
            }
        };
        
        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));
    }

    [Test]
    public async Task ValidateFields_FieldIsNumberAndValueMinusZero_ReturnsSuccessAndNumberSavedIsZero()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("abe34ee2-f3cc-4968-b2a9-892bdc15192f")
                },
                Values = [new () { Value = "-0"}]
            }
        };

        var customField = new CustomField
        {
            Id = 1,
            Guid = new("abe34ee2-f3cc-4968-b2a9-892bdc15192f"),
            FieldType = FieldType.Number,
            DefaultValue = "",
            MinEntries = 0
        };

        var customFields = new List<CustomField>
        {
            customField
        };

        var customFieldNumber = new CustomFieldNumber
        {
            CustomField = customField,
            CustomFieldId = customField.Id,
            MaximumValue = null,
            MinimumValue = null,
            Step = null
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetCustomFieldNumbersAsync(1, It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(customFieldNumber)!);

        //Act
        var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();

        //Assert
        Assert.That(result.Count, Is.EqualTo(1));

        Assert.That(result[0].DisplayValue, Is.EqualTo("0"));
        Assert.That(result[0].Value, Is.EqualTo("0"));
    }

    [Test]
    public void ValidateFields_FieldIsNumberAndValueIsBelowMinimumValue_ThrowsValidationException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("abe34ee2-f3cc-4968-b2a9-892bdc15192f")
                },
                Values = [new () { Value = "2"}]
            }
        };

        var customField = new CustomField
        {
            Id = 1,
            Guid = new("abe34ee2-f3cc-4968-b2a9-892bdc15192f"),
            Name = "TestNumberField1",
            FieldType = FieldType.Number,
            DefaultValue = "",
            MinEntries = 0
        };

        var customFields = new List<CustomField>
        {
            customField,
            
        };

        var customFieldNumber = new CustomFieldNumber
        {
            CustomField = customField,
            CustomFieldId = customField.Id,
            MaximumValue = null,
            MinimumValue =10,
            Step = null
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetCustomFieldNumbersAsync(1, It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(customFieldNumber)!);

        //Assert
        var exception = Assert.ThrowsAsync<ValidationException>(async () =>
        {
            //Act
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });

        Assert.That( exception?.Message, Is.EqualTo($"{customField.Name}: 2 must be greater than or equal to 10"));
    }

    [Test]
    public void ValidateFields_FieldIsNumberAndValueIsAboveMaximumValue_ThrowsValidationException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("abe34ee2-f3cc-4968-b2a9-892bdc15192f")
                },
                Values = [new () { Value = "300"}]
            }
        };

        var customField = new CustomField
        {
            Id = 1,
            Guid = new("abe34ee2-f3cc-4968-b2a9-892bdc15192f"),
            Name = "TestNumberField1",
            FieldType = FieldType.Number,
            DefaultValue = "",
            MinEntries = 0
        };

        var customFields = new List<CustomField>
        {
            customField,

        };

        var customFieldNumber = new CustomFieldNumber
        {
            CustomField = customField,
            CustomFieldId = customField.Id,
            MaximumValue = 200,
            MinimumValue = null,
            Step = null
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetCustomFieldNumbersAsync(1, It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(customFieldNumber)!);

        //Assert
        var exception = Assert.ThrowsAsync<ValidationException>(async () =>
        {
            //Act
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });

        Assert.That(exception?.Message, Is.EqualTo($"{customField.Name}: 300 must be less than or equal to 200"));
    }

    [Test]
    public void ValidateFields_FieldIsNumberAndValueRequiredButNotSupplied_ThrowsValidationException()
    {
        //Arrange
        var customFieldValues = new List<CustomFieldValues>
        {
            new()
            {
                Id = new GeneralIdRef
                {
                    Guid = new Guid("abe34ee2-f3cc-4968-b2a9-892bdc15192f")
                },
                Values = [new () { Value = ""}]
            }
        };

        var customField = new CustomField
        {
            Id = 1,
            Guid = new("abe34ee2-f3cc-4968-b2a9-892bdc15192f"),
            Name = "TestNumberField1",
            FieldType = FieldType.Number,
            DefaultValue = "",
            MinEntries = 1
        };

        var customFields = new List<CustomField>
        {
            customField,

        };

        var customFieldNumber = new CustomFieldNumber
        {
            CustomField = customField,
            CustomFieldId = customField.Id,
            MaximumValue = 200,
            MinimumValue = null,
            Step = null
        };

        _customFieldValidatorRepositoryMock.Setup(x => x.GetCustomFieldNumbersAsync(1, It.IsAny<CancellationToken>()))
            .Returns(Task.FromResult(customFieldNumber)!);

        //Assert
        var exception = Assert.ThrowsAsync<ValidationException>(async () =>
        {
            //Act
            var result = (await _customFieldValidator.ValidateFields(_auditUserDetails, customFieldValues, customFields, default)).ToList();
        });

        Assert.That(exception?.Message, Is.EqualTo($"{customField.Name}: Missing required value"));
    }
}
