using e_suite.Database.Core.Models;
using e_suite.Database.Core.Tables.Domain;
using e_suite.Database.Core.Tables.Forms;
using e_suite.Database.Core.Tables.Glossaries;
using eSuite.Core.CustomFields;

namespace e_suite.Modules.CustomFieldManagerUnitTests.CustomFieldHelperUnitTests;

[TestFixture]
public class CustomFieldValuesListUnitTests : CustomFieldsTestBase<object>
{
    [SetUp]
    public override async Task Setup() => await base.Setup();

    [Test]
    public async Task CustomFieldValuesList_WhenTranslatingSimpleField_ValuesTransferCorrectly()
    {
        //Arrange
        var customField = new CustomField
        {
            Id = 999,
            Guid = new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8"),
            FieldType = FieldType.Text,
            MinEntries = 1,
            MaxEntries = 1,
            DefaultValue = string.Empty
        };

        var customFieldValues = new List<ICustomFieldValue>
        {
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = "Display Test",
                Value = "Test",
                Index = 0
            }
        };

        //Act
        var result = await _customFieldHelper.CustomFieldValuesList(customFieldValues, CancellationToken.None);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Has.Count.EqualTo(1));
            Assert.That(result[0].Id.Id, Is.EqualTo(999));
            Assert.That(result[0].Id.Guid, Is.EqualTo(new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8")));
            Assert.That(result[0].Values, Has.Count.EqualTo(1));
            Assert.That(result[0].Values[0].Value, Is.EqualTo("Test"));
            Assert.That(result[0].Values[0].DisplayValue, Is.EqualTo("Display Test"));
        });
    }

    [Test]
    public async Task CustomFieldValuesList_WhenTranslatingGlossaryField_ValuesTransferCorrectly()
    {
        //Arrange
        var customField = new CustomField
        {
            Id = 999,
            Guid = new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8"),
            FieldType = FieldType.Glossary,
            MinEntries = 1,
            MaxEntries = 1,
            DefaultValue = string.Empty
        };

        _fakeCustomFieldReferenceRepository.Glossaries.Add(new Glossary
        {
            Id = 83,
            Guid = new Guid("2781d151-e0cb-4f6a-b2d9-e0b82b6713a6"),
            Name = "This is a GlossaryItem"
        });

        var customFieldValues = new List<ICustomFieldValue>
        {
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = "This is a GlossaryItem",
                Value = "2781d151-e0cb-4f6a-b2d9-e0b82b6713a6",
                Index = 0
            }
        };

        //Act
        var result = await _customFieldHelper.CustomFieldValuesList(customFieldValues, CancellationToken.None);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Has.Count.EqualTo(1));
            Assert.That(result[0].Id.Id, Is.EqualTo(999));
            Assert.That(result[0].Id.Guid, Is.EqualTo(new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8")));
            Assert.That(result[0].Values, Has.Count.EqualTo(1));
            Assert.That(result[0].Values[0].Value, Is.Not.Null);
            Assert.That(result[0].Values[0].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Id, Is.EqualTo(83));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Guid, Is.EqualTo(new Guid("2781d151-e0cb-4f6a-b2d9-e0b82b6713a6")));
            Assert.That(result[0].Values[0].DisplayValue, Is.EqualTo("This is a GlossaryItem"));
        });
    }

    [Test]
    public async Task CustomFieldValuesList_WhenTranslatingGlossaryFieldWithMultipleValues_ValuesTransferCorrectly()
    {
        //Arrange
        var customField = new CustomField
        {
            Id = 999,
            Guid = new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8"),
            FieldType = FieldType.Glossary,
            MinEntries = 1,
            MaxEntries = null,
            DefaultValue = string.Empty
        };

        _fakeCustomFieldReferenceRepository.Glossaries.Add(new Glossary
        {
            Id = 83,
            Guid = new Guid("2781d151-e0cb-4f6a-b2d9-e0b82b6713a6"),
            Name = "This is a GlossaryItem"
        });

        _fakeCustomFieldReferenceRepository.Glossaries.Add(new Glossary
        {
            Id = 84,
            Guid = new Guid("B22C0DA9-280B-4CC8-AA55-C88BAAE18D66"),
            Name = "Item 2"
        });


        var customFieldValues = new List<ICustomFieldValue>
        {
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = "This is a GlossaryItem",
                Value = "2781d151-e0cb-4f6a-b2d9-e0b82b6713a6",
                Index = 0
            },
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = "Item 2",
                Value = "B22C0DA9-280B-4CC8-AA55-C88BAAE18D66",
                Index = 1
            }
        };

        //Act
        var result = await _customFieldHelper.CustomFieldValuesList(customFieldValues, CancellationToken.None);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Has.Count.EqualTo(1));
            Assert.That(result[0].Id.Id, Is.EqualTo(999));
            Assert.That(result[0].Id.Guid, Is.EqualTo(new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8")));
            

            Assert.That(result[0].Values, Has.Count.EqualTo(2));
            
            Assert.That(result[0].Values[0].Value, Is.Not.Null);
            Assert.That(result[0].Values[0].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Id, Is.EqualTo(83));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Guid, Is.EqualTo(new Guid("2781d151-e0cb-4f6a-b2d9-e0b82b6713a6")));
            Assert.That(result[0].Values[0].DisplayValue, Is.EqualTo("This is a GlossaryItem"));

            Assert.That(result[0].Values[1].Value, Is.Not.Null);
            Assert.That(result[0].Values[1].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[1].Value)).Id, Is.EqualTo(84));
            Assert.That(((GeneralIdRef)(result[0].Values[1].Value)).Guid, Is.EqualTo(new Guid("B22C0DA9-280B-4CC8-AA55-C88BAAE18D66")));
            Assert.That(result[0].Values[1].DisplayValue, Is.EqualTo("Item 2"));

        });
    }

    [Test]
    public async Task CustomFieldValuesList_WhenTranslatingDomainField_ValuesTransferCorrectly()
    {
        //Arrange
        var customField = new CustomField
        {
            Id = 999,
            Guid = new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8"),
            FieldType = FieldType.Domain,
            MinEntries = 1,
            MaxEntries = 1,
            DefaultValue = string.Empty
        };

        _fakeCustomFieldReferenceRepository.Domains.Add(new Domain
        {
            Id = 13,
            Guid = new Guid("5ffcf209-15c6-4924-8570-6415a639c4a4"),
            Name = "Test Domain"
        });

        var customFieldValues = new List<ICustomFieldValue>
        {
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = "DomainItem",
                Value = "5ffcf209-15c6-4924-8570-6415a639c4a4",
                Index = 0
            }
        };

        //Act
        var result = await _customFieldHelper.CustomFieldValuesList(customFieldValues, CancellationToken.None);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Has.Count.EqualTo(1));
            Assert.That(result[0].Id.Id, Is.EqualTo(999));
            Assert.That(result[0].Id.Guid, Is.EqualTo(new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8")));
            Assert.That(result[0].Values, Has.Count.EqualTo(1));
            Assert.That(result[0].Values[0].Value, Is.Not.Null);
            Assert.That(result[0].Values[0].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Id, Is.EqualTo(13));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Guid, Is.EqualTo(new Guid("5ffcf209-15c6-4924-8570-6415a639c4a4")));
            Assert.That(result[0].Values[0].DisplayValue, Is.EqualTo("DomainItem"));
        });
    }

    [Test]
    public async Task CustomFieldValuesList_WhenTranslatingDomainFieldWithMultipleValues_ValuesTransferCorrectly()
    {
        //Arrange
        var customField = new CustomField
        {
            Id = 999,
            Guid = new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8"),
            FieldType = FieldType.Domain,
            MinEntries = 1,
            MaxEntries = null,
            DefaultValue = string.Empty
        };

        var domainOneGuid = "9dc6f024-c02c-4674-8e33-362f636f8ce4";
        var domainTwoGuid = "a9890395-8782-4b3e-878b-efdb8fba3c12";
        var domainOneName = "Domain One";
        var domainTwoName = "Domain Two";

        _fakeCustomFieldReferenceRepository.Domains.Add(new Domain
        {
            Id = 83,
            Guid = new Guid(domainOneGuid),
            Name = domainOneName
        });

        _fakeCustomFieldReferenceRepository.Domains.Add(new Domain
        {
            Id = 84,
            Guid = new Guid(domainTwoGuid),
            Name = domainTwoName
        });

        var customFieldValues = new List<ICustomFieldValue>
        {
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = domainOneName,
                Value = domainOneGuid,
                Index = 0
            },
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = domainTwoName,
                Value = domainTwoGuid,
                Index = 1
            }
        };

        //Act
        var result = await _customFieldHelper.CustomFieldValuesList(customFieldValues, CancellationToken.None);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Has.Count.EqualTo(1));
            Assert.That(result[0].Id.Id, Is.EqualTo(999));
            Assert.That(result[0].Id.Guid, Is.EqualTo(new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8")));

            Assert.That(result[0].Values, Has.Count.EqualTo(2));

            Assert.That(result[0].Values[0].Value, Is.Not.Null);
            Assert.That(result[0].Values[0].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Id, Is.EqualTo(83));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Guid, Is.EqualTo(new Guid(domainOneGuid)));
            Assert.That(result[0].Values[0].DisplayValue, Is.EqualTo(domainOneName));

            Assert.That(result[0].Values[1].Value, Is.Not.Null);
            Assert.That(result[0].Values[1].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[1].Value)).Id, Is.EqualTo(84));
            Assert.That(((GeneralIdRef)(result[0].Values[1].Value)).Guid, Is.EqualTo(new Guid(domainTwoGuid)));
            Assert.That(result[0].Values[1].DisplayValue, Is.EqualTo(domainTwoName));
        });
    }

    [Test]
    public async Task CustomFieldValuesList_WhenTranslatingTemplateField_ValuesTransferCorrectly()
    {
        //Arrange
        var customField = new CustomField
        {
            Id = 999,
            Guid = new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8"),
            FieldType = FieldType.FormTemplate,
            MinEntries = 1,
            MaxEntries = 1,
            DefaultValue = string.Empty
        };

        _fakeCustomFieldReferenceRepository.FormTemplates.Add(new FormTemplate()
        {
            Id = 76,
            Guid = new Guid("74c51c57-e23e-4d0a-ad7d-273acc6883ce"),
            Name = "My Test Form Template"
        });

        var customFieldValues = new List<ICustomFieldValue>
        {
            new FormFieldInstance
            {
                CustomField = customField,
                CustomFieldId = customField.Id,
                DisplayValue = "My Test Form Template",
                Value = "74c51c57-e23e-4d0a-ad7d-273acc6883ce",
                Index = 0
            }
        };

        //Act
        var result = await _customFieldHelper.CustomFieldValuesList(customFieldValues, CancellationToken.None);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result, Has.Count.EqualTo(1));
            Assert.That(result[0].Id.Id, Is.EqualTo(999));
            Assert.That(result[0].Id.Guid, Is.EqualTo(new Guid("dca50da4-03d6-438e-bf90-c2ef11f455d8")));
            Assert.That(result[0].Values, Has.Count.EqualTo(1));
            Assert.That(result[0].Values[0].Value, Is.Not.Null);
            Assert.That(result[0].Values[0].Value, Is.AssignableTo(typeof(GeneralIdRef)));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Id, Is.EqualTo(76));
            Assert.That(((GeneralIdRef)(result[0].Values[0].Value)).Guid, Is.EqualTo(new Guid("74c51c57-e23e-4d0a-ad7d-273acc6883ce")));
            Assert.That(result[0].Values[0].DisplayValue, Is.EqualTo("My Test Form Template"));
        });
    }
}