using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.Database.Core.Tables.Forms;
using e_suite.Database.Core.Tables.Glossaries;
using eSuite.Core.CustomFields;
using Sequence = e_suite.Database.Core.Tables.Sequences.Sequence;

namespace e_suite.Modules.CustomFieldManagerUnitTests.CustomFieldManagerUnitTests;

public class EditCustomFieldUnitTests : CustomFieldsTestBase<object>
{

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

    [Test]
    public void EditCustomField_NoRefObj_ThrowsNameExistsException()
    {
        var customFieldInDb = new CustomField
        {
            DefaultValue = "test",
            FieldType = eSuite.Core.CustomFields.FieldType.Time,
            Name = "NameExists",
            Id = 10
        };

        var customField = new CustomField
        {
            DefaultValue = "testOne",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "TestOrg",
            Id = 15
        };
        _fakeCustomFieldRepository.CustomFields.Add(customFieldInDb);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "Testt",
            Name = "NameExists",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Id = new GeneralIdRef
            {
                Guid = null,
                Id = 15
            }
        };
        Assert.ThrowsAsync<ExistsException>(() => _customFieldManager.EditFieldAsync(auditResult, editCustomField, default));
    }

    [Test]
    public void EditCustomField_UnexistingId_ThrowsExeption()
    {
        var baseGuid = new Guid("dfeeb83d-d12d-439d-a6c4-7ff987467d8d");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Guid = baseGuid,
            Name = "Test",
            Id = 5,
        }; ;
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        var editcustomField = new EditCustomFields
        {
            DefaultValue = "some",
            FieldType = eSuite.Core.CustomFields.FieldType.FormTemplate,
            Name = "Someee",
            Id = new GeneralIdRef
            {
                Guid = new Guid("47bc6bf4-9afc-407e-ad13-b6f90cb84e1b"),
                Id = 2
            },
        };
        Assert.ThrowsAsync<NotFoundException>(() => _customFieldManager.EditFieldAsync(auditResult, editcustomField, default));
    }

    [Test]
    public async Task EditCustomField_NormalConditions_SaveChanges()
    {
        var baseGuid = new Guid("c1aa4f0a-a0c7-4c54-a72c-4ae5d5ccbd7b");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Guid = baseGuid,
            Name = "Test",
            Id = 5,
            MinEntries = 10,
            MaxEntries = 10
        };

        _fakeCustomFieldRepository.CustomFields.Add(customField);
        var res = await _fakeCustomFieldRepository.GetByIdAsync(new GeneralIdRef
        {
            Guid = baseGuid,
            Id = 5
        }, default);
        Assert.Multiple(() =>
        {
            Assert.That(res?.DefaultValue, Is.EqualTo(customField.DefaultValue));
            Assert.That(res!.Name, Is.EqualTo(customField.Name));
            Assert.That(res!.MinEntries, Is.EqualTo(10));
            Assert.That(res.MaxEntries, Is.EqualTo(10));
        });
    }

    [Test]
    public async Task EditCustomField_AllPossibleFieldValuesSetToNull_SaveChanges()
    {
        var baseGuid = new Guid("ee47538e-77f3-4b0b-ad9a-7871eed1884c");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Guid = baseGuid,
            Name = "Test",
            Id = 5,
        };
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        var editCustomField = new EditCustomFields
        {
            DefaultValue = "some",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "Name",
            Id = new GeneralIdRef
            {
                Guid = baseGuid,
                Id = 5
            },
            Parameters = "{\"multiLine\":false}"
        };
        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);
        var res = await _fakeCustomFieldRepository.GetByIdAsync(new GeneralIdRef
        {
            Guid = baseGuid,
            Id = 5
        }, default);
        Assert.Multiple(() =>
        {
            Assert.That(res?.DefaultValue, Is.EqualTo("some"));
            Assert.That(res!.Name, Is.EqualTo("Name"));
        });
    }

    [Test]
    public void EditCustomField_NullForGuidAndId_ThrowsException()
    {
        var baseGuid = new Guid("f2c1a107-a748-410d-9192-aebac5151207");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Guid = baseGuid,
            Name = "Test",
            Id = 5,
        }; ;
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        var editcustomField = new EditCustomFields
        {
            DefaultValue = "some",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "name",
            Id = new GeneralIdRef
            {
                Guid = null,
                Id = null
            },
        };
        Assert.ThrowsAsync<NotFoundException>(() => _customFieldManager.EditFieldAsync(auditResult, editcustomField, default));
    }

    [Test]
    public async Task EditCustomField_IdFieldOnlyHasIdNoGuid_SaveChanges()
    {
        var baseGuid = new Guid("7de35ae2-0cb2-44a0-a98b-6eff6097b156");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Guid = baseGuid,
            Name = "Test",
            Id = 5,
        }; ;
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        var editcustomField = new EditCustomFields
        {
            DefaultValue = "Tessst",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "Some1",
            Id = new GeneralIdRef
            {
                Guid = null,
                Id = 5
            },
            Parameters = "{\"multiLine\":false}"
        };
        await _customFieldManager.EditFieldAsync(auditResult, editcustomField, default);
        var res = await _fakeCustomFieldRepository.GetByIdAsync(new GeneralIdRef
        {
            Guid = null,
            Id = 5
        }, default);
        Assert.Multiple(() =>
        {
            Assert.That(res, Is.Not.Null);
            Assert.That(res!.DefaultValue, Is.EqualTo("Tessst"));
            Assert.That(res.Name, Is.EqualTo("Some1"));
        });
    }
    
    [Test]
    public async Task EditCustomField_DifferentReferenceSequenceNoRefObjForDeletion_SaveChanges()
    {
        var customFieldId = new Guid("3c0b6eeb-dfa3-4539-995f-b94b067d861d");
        var sequenceGuid = new Guid("fcf96e58-c00d-4ba2-baae-6e6bedc923f7");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "Test",
            Guid = customFieldId,
            Id = 1,
            MinEntries = 1,
            MaxEntries = 1
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "Testtt",
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "Test111111",
            RefElementId = new GeneralIdRef
            {
                Guid = sequenceGuid,
                Id = 5,
            },
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            MinEntries = 1,
            MaxEntries = 1
        };

        var sequence = new Sequence
        {
            Guid = sequenceGuid,
            Id = 5,
            Deleted = false,
            Name = "NameSequence",
            Increment = 1,
        };

        _fakeCustomFieldReferenceRepository.Sequences.Add(sequence);
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        
        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);
        
        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldSequences, Has.Count.EqualTo(1));
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldSequences[0].CustomFieldId, Is.EqualTo(1));
            Assert.That(_fakeCustomFieldRepository.CustomFields[0].Name, Is.EqualTo("Test111111"));
        });
    }

    [Test]
    public async Task EditCustomField_DifferentReferenceGlossaryNoneObjForDeletion_SaveChanges()
    {
        var customFieldId = new Guid("b57ede2d-5f21-4399-9b17-7ba356daf32d");
        var glossaryId = new Guid("b87a3a12-6e20-43ac-a54c-3188213109c9");

        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "Test",
            Guid = customFieldId,
            Id = 1,
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "au",
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Name = "TestSSSTest",
            RefElementId = new GeneralIdRef
            {
                Guid = glossaryId,
                Id = 5,
            },
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },

        };

        var glossary = new Glossary
        {
            Guid = glossaryId,
            Id = 5,
            Deleted = false,
            Name = "NameForm",
        };

        _fakeCustomFieldRepository.CustomFields.Add(customField);
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossary);
        
        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);
        
        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries, Has.Count.EqualTo(1));
            Assert.That(_fakeCustomFieldRepository.CustomFields[0].Name, Is.EqualTo("TestSSSTest"));
            Assert.That(_fakeCustomFieldRepository.CustomFields[0].DefaultValue, Is.EqualTo("au"));
        });
    }

    [Test]
    public async Task EditCustomField_CustomFieldWithSequenceReferenceToBasicType_SaveChanges()
    {
        var customFieldId = new Guid("7dc5e45f-cc56-4e71-942c-6463b7bd43d5");
        var sequenceGuid = new Guid("0a344546-1f57-4bd2-8ffa-105ebffb9719");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "Test",
            Guid = customFieldId,
            Id = 1,
        };

        var sequence = new Sequence
        {
            Guid = sequenceGuid,
            Id = 5,
            Deleted = false,
            Name = "NameSequence",
            Increment = 1,
        };

        var customFieldSequence = new CustomFieldSequence
        {
            CustomFieldId = 1,
            SequenceId = 5
        };

        var editCustomFeild = new EditCustomFields
        {
            DefaultValue = "FEF",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "FEFName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            Parameters = "{\"multiLine\":false}"
        };

        _fakeCustomFieldRepository.CustomFields.Add(customField);
        _fakeCustomFieldReferenceRepository.CustomFieldSequences.Add(customFieldSequence);
        _fakeCustomFieldReferenceRepository.Sequences.Add(sequence);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomFeild, default);
        
        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldSequences, Has.Count.EqualTo(0));
            Assert.That(customField.Name, Is.EqualTo("FEFName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("FEF"));
        });

    }

    [Test]
    public async Task EditCustomField_CustomFieldWithGlossaryReferenceToBasicType_SaveChanges()
    {
        var customFieldId = new Guid("f4449135-acf5-427b-8597-a29c2a46c7c9");
        var glossaryGuid = new Guid("7ff16821-c1f8-476f-8b5d-c48100674b02");
        var customField = new CustomField
        {
            DefaultValue = "asdasd",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Name = "Test",
            Guid = customFieldId,
            Id = 1,
        };

        var glossary = new Glossary
        {
            Guid = glossaryGuid,
            Id = 5,
            Deleted = false,
            Name = "NameSequence",
            Parent = null!
        };

        var customFieldGlossary = new CustomFieldGlossary
        {
            CustomFieldId = 1,
            GlossaryId = 5
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "FEF",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "FEFName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            Parameters = "{\"multiLine\":false}"
        };
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossary);
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        _fakeCustomFieldReferenceRepository.CustomFieldGlossaries.Add(customFieldGlossary);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries, Has.Count.EqualTo(0));
            Assert.That(customField.Name, Is.EqualTo("FEFName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("FEF"));
        });
    }

    [Test]
    public async Task EditCustomField_CustomFieldWithFormReferenceToCreateOneGlossaryAndDeleteFormObj_SaveChanges()
    {
        var customFieldId = new Guid("b1d17211-1399-4a1c-ae03-fed49c649426");
        var formGuid = new Guid("65dc687e-c8bb-4288-b0c6-b7f39cfde836");
        var glossaryGuid = new Guid("d416496f-d0f2-4ee3-a821-afb8c3bd0a14");
        var customField = new CustomField
        {
            DefaultValue = "FormTemplateValue",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.FormTemplate,
            Name = "FormName",
            Guid = customFieldId,
            Id = 1,
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "GlossaryDefault",
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Name = "FEGlossaryName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = new GeneralIdRef
            {
                Id = 20,
                Guid = glossaryGuid
            },
            MinEntries = 10,
            MaxEntries = 10,
        };
        
        var glossary = new Glossary
        {
            Guid = glossaryGuid,
            Deleted = false,
            Name = "gloss",
            Id = 20
        };

        var formTemplate = new FormTemplate
        {
            Guid = formGuid,
            Id = 5,
            Deleted = false,
            Name = "NameForm",
        };
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossary);
        _fakeCustomFieldReferenceRepository.FormTemplates.Add(formTemplate);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries, Has.Count.EqualTo(1));
            Assert.That(customField.Name, Is.EqualTo("FEGlossaryName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("GlossaryDefault"));
            Assert.That(customField.MaxEntries, Is.EqualTo(10));
            Assert.That(customField.MinEntries, Is.EqualTo(10));
        });
    }

    [Test]
    public async Task EditCustomField_CustomFieldWithGlossaryReferenceToCreateOneSequenceAndDeleteGlossaryObj_SaveChanges()
    {
        var customFieldId = new Guid("64661af7-ef5a-4ee1-84e5-59327ff62625");
        var glossaryGuid = new Guid("a3ad8c4e-112d-41fc-881e-e450b84c5c12");
        var sequenceGuid = new Guid("36ca4348-a779-485d-9d90-04766207d2a1");
        var customField = new CustomField
        {
            DefaultValue = "GlossaryValue",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Name = "Glosss",
            Guid = customFieldId,
            Id = 1,
            MaxEntries = 1,
            MinEntries = 1,
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "SequenceDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "SequenceName",
            MinEntries = 1,
            MaxEntries = 1,
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = new GeneralIdRef
            {
                Id = 20,
                Guid = sequenceGuid
            }
        };

        var customFieldGlossary = new CustomFieldGlossary
        {
            CustomFieldId = 1,
            GlossaryId = 5
        };

        var sequence = new Sequence
        {
            Guid = sequenceGuid,
            Deleted = false,
            Name = "Dasda",
            Id = 20,
            Increment = 5
        };

        var glossary = new Glossary
        {
            Guid = glossaryGuid,
            Id = 5,
            Deleted = false,
            Name = "NEwGloss",
        };
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossary);
        _fakeCustomFieldReferenceRepository.CustomFieldGlossaries.Add(customFieldGlossary);
        _fakeCustomFieldReferenceRepository.Sequences.Add(sequence);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldSequences, Has.Count.EqualTo(1));
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries, Has.Count.EqualTo(0));
            Assert.That(customField.Name, Is.EqualTo("SequenceName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("SequenceDef"));
            Assert.That(customField.MaxEntries, Is.EqualTo(1));
            Assert.That(customField.MinEntries, Is.EqualTo(1));
        });
    }

    [Test]
    public async Task EditCustomField_CustomFieldWithSequenceReferenceToCreateOneGlossaryAndDeleteSequenceObj_SaveChanges()
    {
        var customFieldId = new Guid("fc281499-2991-4d04-9bc1-f833be690f80");
        var glossaryGuid = new Guid("b0b816a7-63b1-485d-b067-1ae3edd3ff6e");
        var sequenceGuid = new Guid("a0c63632-4ee7-44a1-a18d-128414a0a262");
        var customField = new CustomField
        {
            DefaultValue = "Sequencevalue",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "Sequ",
            Guid = customFieldId,
            Id = 1,
            MinEntries = 1,
            MaxEntries = 1,
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "GloosaryDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Name = "GlossaryName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = new GeneralIdRef
            {
                Id = 5,
                Guid = glossaryGuid
            },
            MinEntries = 10,
            MaxEntries = 10,
        };

        var customFieldSequence = new CustomFieldSequence
        {
            CustomFieldId = 1,
            SequenceId = 20
        };

        var sequence = new Sequence
        {
            Guid = sequenceGuid,
            Deleted = false,
            Name = "Dasda",
            Id = 20,
            Increment = 5
        };

        var glossary = new Glossary
        {
            Guid = glossaryGuid,
            Id = 5,
            Deleted = false,
            Name = "NEwGloss",
        };
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossary);
        _fakeCustomFieldReferenceRepository.Sequences.Add(sequence);
        _fakeCustomFieldReferenceRepository.CustomFieldSequences.Add(customFieldSequence);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldSequences, Has.Count.EqualTo(0));
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries, Has.Count.EqualTo(1));
            Assert.That(customField.Name, Is.EqualTo("GlossaryName"));
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries[0].CustomFieldId, Is.EqualTo(1));
            Assert.That(customField.MaxEntries, Is.EqualTo(10));
            Assert.That(customField.MinEntries, Is.EqualTo(10));
        });
    }

    [Test]
    public async Task EditCustomField_CustomFieldWithGlossaryReferenceToTestType_SaveChanges()
    {
        var customFieldId = new Guid("e9ccf611-2900-4dad-8850-27c89a3571a3");
        var glossaryGuid = new Guid("a983587c-0d71-47c0-b967-f2ae181c490f");

        var customField = new CustomField
        {
            DefaultValue = "DefaultStart",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Guid = customFieldId,
            Id = 1,
            Name = "NameStart",
            MinEntries = 1,
            MaxEntries = 1,
        };

        var glossary = new Glossary
        {
            Guid = glossaryGuid,
            Id = 5,
            Deleted = false,
            Name = "NEwGloss",
        };

        var customFieldGlossary = new CustomFieldGlossary
        {
            CustomFieldId = 1,
            GlossaryId = 5
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "EditValue",
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Name = "EditName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            MinEntries = 10,
            MaxEntries = 10,
            Parameters = "{\"multiLine\":false}"
        };
        _fakeCustomFieldReferenceRepository.CustomFieldGlossaries.Add(customFieldGlossary);
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossary);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries, Has.Count.EqualTo(0));
            Assert.That(customField.Name, Is.EqualTo("EditName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("EditValue"));
            Assert.That(customField.MaxEntries, Is.EqualTo(10));
            Assert.That(customField.MinEntries, Is.EqualTo(10));
        });
    }

    [Test]
    public async Task EditCustomField_SameObjReferenceUpdateReferenceGlossary_SaveChanges()
    {
        var customFieldId = new Guid("4dcbac9a-0e8b-4022-be66-bca94e1fa0c3");
        var glossaryGuidOld = new Guid("e11f3a48-8e43-4c56-a7ea-0e3ddb96ae21");
        var glossaryGuidNew = new Guid("d748a83e-0343-48e1-939e-c27db2289c6d");

        var customField = new CustomField
        {
            DefaultValue = "DefaultStart",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Guid = customFieldId,
            Id = 1,
            Name = "NameStart",
            MinEntries = 1,
            MaxEntries = 1,
        };

        var glossaryOld = new Glossary
        {
            Deleted = false,
            Guid = glossaryGuidOld,
            Id = 5,
            Name = "Before"
        };

        var glossaryNew = new Glossary
        {
            Deleted = false,
            Guid = glossaryGuidNew,
            Id = 10,
            Name = "New"
        };

        var customFieldGlossary = new CustomFieldGlossary
        {
            CustomFieldId = 1,
            GlossaryId = 10
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "NewGlossDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Glossary,
            Name = "NewGlossName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = new GeneralIdRef
            {
                Id = 10,
                Guid = glossaryGuidNew
            },
            MinEntries = 10,
            MaxEntries = 10,
        };
        _fakeCustomFieldReferenceRepository.CustomFieldGlossaries.Add(customFieldGlossary);
        _fakeCustomFieldRepository.CustomFields.Add(customField);
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossaryOld);
        _fakeCustomFieldReferenceRepository.Glossaries.Add(glossaryNew);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldGlossaries[0].GlossaryId, Is.EqualTo(10));
            Assert.That(customField.Name, Is.EqualTo("NewGlossName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("NewGlossDef"));
            Assert.That(customField.MaxEntries, Is.EqualTo(10));
            Assert.That(customField.MinEntries, Is.EqualTo(10));
        });

    }

    [Test]
    public async Task EditCustomField_SameObjReferenceUpdateReferenceSequence_SaveChanges()
    {
        var customFieldId = new Guid("a14ae0dd-12e8-4788-961f-25cdaa70f40f");
        var sequenceGuidOld = new Guid("8ef35a06-96cf-40d5-92be-597913d4ad1c");
        var sequenceGuidNew = new Guid("576d202c-31e3-44f4-8ca6-23518951567b");

        var customField = new CustomField
        {
            DefaultValue = "DefaultStart",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Guid = customFieldId,
            Id = 1,
            Name = "NameStart",
            MinEntries = 1,
            MaxEntries = 1,
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "NewSequenceDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "NewSequenceName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = new GeneralIdRef
            {
                Id = 10,
                Guid = sequenceGuidNew
            },
            MinEntries = 1,
            MaxEntries = 1,
        };

        var sequenceOld = new Sequence
        {
            Deleted = false,
            Name = "OldSeq",
            Guid = sequenceGuidOld,
            Id = 5,
            Seed = 1
        };

        var sequenceNew = new Sequence
        {
            Deleted = false,
            Name = "NewSeq",
            Guid = sequenceGuidNew,
            Id = 10,
            Seed = 1
        };

        var customFieldSequence = new CustomFieldSequence
        {
            CustomFieldId = 1,
            SequenceId = 5
        };

        _fakeCustomFieldReferenceRepository.Sequences.AddRange(new Sequence[] { sequenceOld, sequenceNew });
        _fakeCustomFieldReferenceRepository.CustomFieldSequences.Add(customFieldSequence);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);

        Assert.Multiple(() =>
        {
            Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldSequences[0].SequenceId, Is.EqualTo(10));
            Assert.That(customField.Name, Is.EqualTo("NewSequenceName"));
            Assert.That(customField.DefaultValue, Is.EqualTo("NewSequenceDef"));
            Assert.That(customField.MaxEntries, Is.EqualTo(1));
            Assert.That(customField.MinEntries, Is.EqualTo(1));
        });
    }

    [Test]
    public void EditCustomField_SameObjectTypeReferenceWithUnexistingRefObject_ThrowsException()
    {
        var customFieldId = new Guid("439c1876-61b7-44df-b516-1107c52152c2");
        var sequenceGuidOld = new Guid("c0bdd715-4bf6-41fa-b2e0-168181170491");
        var sequenceGuidNew = new Guid("5e3b96fd-77aa-48d5-bf1c-a69f3d6d0c17");

        var customField = new CustomField
        {
            DefaultValue = "DefaultStart",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Guid = customFieldId,
            Id = 1,
            Name = "NameStart",
            MinEntries = 1,
            MaxEntries = 1,
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "NewSequenceDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "NewSequenceName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = new GeneralIdRef
            {
                Id = 10,
                Guid = sequenceGuidNew
            },
            MinEntries = 10,
            MaxEntries = 10,
        };

        var sequenceOld = new Sequence
        {
            Deleted = false,
            Name = "OldSeq",
            Guid = sequenceGuidOld,
            Id = 5,
            Seed = 1
        };

        var customFieldSequence = new CustomFieldSequence
        {
            CustomFieldId = 1,
            SequenceId = 5
        };

        _fakeCustomFieldReferenceRepository.Sequences.Add(sequenceOld);
        _fakeCustomFieldReferenceRepository.CustomFieldSequences.Add(customFieldSequence);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        Assert.ThrowsAsync<InvalidReferenceObjectId>(() => _customFieldManager.EditFieldAsync(auditResult, editCustomField, default));
    }

    [Test]
    public void EditCustomField_EditFieldWithReferenceNull_ThrowsException()
    {

        var customFieldId = new Guid("8952dfb2-6c08-4bbc-8b61-2e66b90a3558");
        var sequenceGuidOld = new Guid("158d8946-76ee-44b4-bcb2-5390bc4d606a");
        var sequenceGuidNew = new Guid("b359cc4d-3c7c-4b1f-9933-2c5921530c9f");

        var customField = new CustomField
        {
            DefaultValue = "DefaultStart",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Guid = customFieldId,
            Id = 1,
            Name = "NameStart"
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "NewSequenceDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "NewSequenceName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = null!
        };

        var sequenceOld = new Sequence
        {
            Deleted = false,
            Name = "OldSeq",
            Guid = sequenceGuidOld,
            Id = 5,
            Seed = 1
        };

        _fakeCustomFieldReferenceRepository.Sequences.Add(sequenceOld);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        Assert.ThrowsAsync<InvalidReferenceObjectId>(() => _customFieldManager.EditFieldAsync(auditResult, editCustomField, default));
    }

    [Test]
    public void EditCustomField_EditFieldWithReferenceNullSecondWay_ThrowsException()
    {
        //Arrange
        var customFieldId = new Guid("3fe78133-cf5f-47fb-b14e-1ba3d19a9867");
        var sequenceGuidOld = new Guid("8705dadc-bd58-45d8-9ede-2515868b081b");
        var sequenceGuidNew = new Guid("277fa0e0-b9f4-4afb-b9bd-0149653d9726");

        var customField = new CustomField
        {
            DefaultValue = "DefaultStart",
            Deleted = false,
            FieldType = eSuite.Core.CustomFields.FieldType.Text,
            Guid = customFieldId,
            Id = 1,
            Name = "NameStart"
        };

        var editCustomField = new EditCustomFields
        {
            DefaultValue = "NewSequenceDef",
            FieldType = eSuite.Core.CustomFields.FieldType.Sequence,
            Name = "NewSequenceName",
            Id = new GeneralIdRef
            {
                Id = 1,
                Guid = customFieldId
            },
            RefElementId = null!
        };

        var sequenceOld = new Sequence
        {
            Deleted = false,
            Name = "OldSeq",
            Guid = sequenceGuidOld,
            Id = 5,
            Seed = 1
        };

        _fakeCustomFieldReferenceRepository.Sequences.Add(sequenceOld);
        _fakeCustomFieldRepository.CustomFields.Add(customField);

        //Assert
        Assert.ThrowsAsync<InvalidReferenceObjectId>(async() =>
        {
            //Act
            await _customFieldManager.EditFieldAsync(auditResult, editCustomField, default);
        });
    }

    [Test]
    public async Task EditCustomField_EditNumberFieldToText_DeletesCustomNumberEntry()
    {
        //Arrange
        var customField = new CustomField
        {
            Guid = new Guid("89977847-5693-4f4b-8a8a-e576d0b6da4c"),
            Id = 1,
            FieldType = FieldType.Number,
            MinEntries = 1,
            MaxEntries = 1,
            DefaultValue = string.Empty,
            Deleted = false,
            Name = "Test custom field"
        };

        _fakeCustomFieldRepository.CustomFields.Add(customField);

        var customFieldNumber = new CustomFieldNumber
        {
            CustomField = customField,
            CustomFieldId = customField.Id,
            MaximumValue = 200,
            MinimumValue = 0,
            Step = null
        };
        _fakeCustomFieldReferenceRepository.CustomFieldNumber.Add(customFieldNumber);


        var editCustomField = new EditCustomFields
        {
            DefaultValue = "",
            FieldType = FieldType.Text,
            Name = "Test custom field",
            Id = new GeneralIdRef
            {
                Id = customField.Id,
                Guid = customField.Guid
            },
            Parameters = "{\"multiLine\":false}"
        };

        //Act
        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, CancellationToken.None);

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

    [Test]
    public async Task EditCustomField_EditNumberField_ReplacesExpectedValues()
    {
        //Arrange
        var customField = new CustomField
        {
            Guid = new Guid("89977847-5693-4f4b-8a8a-e576d0b6da4c"),
            Id = 1,
            FieldType = FieldType.Number,
            MinEntries = 1,
            MaxEntries = 1,
            DefaultValue = string.Empty,
            Deleted = false,
            Name = "Test custom field"
        };

        _fakeCustomFieldRepository.CustomFields.Add(customField);

        var customFieldNumber = new CustomFieldNumber
        {
            CustomField = customField,
            CustomFieldId = customField.Id,
            MaximumValue = 200,
            MinimumValue = 0,
            Step = null
        };
        _fakeCustomFieldReferenceRepository.CustomFieldNumber.Add(customFieldNumber);


        var editCustomField = new EditCustomFields
        {
            DefaultValue = "",
            FieldType = FieldType.Number,
            Name = "Test custom field",
            Id = new GeneralIdRef
            {
                Id = customField.Id,
                Guid = customField.Guid
            },
            Parameters = "{ \"minValue\":\"2.3\", \"maxValue\": \"99.99\", \"step\": \"0.2\" }"
        };

        //Act
        await _customFieldManager.EditFieldAsync(auditResult, editCustomField, CancellationToken.None);

        //Assert
        Assert.That(_fakeCustomFieldReferenceRepository.CustomFieldNumber.Count, Is.EqualTo(1));
        var editedResult = _fakeCustomFieldReferenceRepository.CustomFieldNumber[0];

        Assert.That(editedResult.MinimumValue, Is.EqualTo(2.3));
        Assert.That(editedResult.MaximumValue, Is.EqualTo(99.99));
        Assert.That(editedResult.Step, Is.EqualTo(0.2));
    }
}