using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.Database.Core.Tables.Forms;
using eSuite.Core.Miscellaneous;
using NUnit.Framework;

namespace e_suite.Modules.FormsManagerUnitTests.FormsManagerUnitTests;

public class EditFormUnitTest : FormsManagerUnitTestBase
{
    [SetUp]
    public async Task SetUp()
    {
        await base.Setup();
    }

    [Test]
    public async Task EditForm_NormalConditions_SaveChanges()
    {
        //Arrange
        var form = new FormTemplate
        {
            Guid = Guid.NewGuid(),
            Deleted = false,
            Id = 1,
            Name = "Test",
        };

        var formVersion = new FormTemplateVersion
        {
            Deleted = false,
            FormDefinition = "testttt",
            Id = 1,
            Guid = Guid.NewGuid(),
            TemplateId = 1,
            Template = form
        };
            
        form.Versions = [ formVersion ];
        _fakeformRepository.FormTemplateVersions.Add(formVersion);
        _fakeformRepository.FormTemplates.Add(form);
            
        var editForm = new EditFormTemplate
        {
            Definition = "EditedDef",
            Name = "Edited",
            Id = new GeneralIdRef
            {
                Id = 1
            }
        };

        //Act
        await _formManager.EditFormTemplateAsync(auditResult, editForm, default);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(_fakeformRepository.FormTemplateVersions, Has.Count.EqualTo(2));
            Assert.That(_fakeformRepository.FormTemplateVersions[1].Version, Is.EqualTo(1));
            Assert.That(_fakeformRepository.FormTemplates[0].Name, Is.EqualTo("Edited"));
        });
    }
    [Test]
    public void EditForm_NotExistingForm_ThrowException()
    {
        //Arrange
        var editForm = new EditFormTemplate
        {
            Definition = "EditedDef",
            Name = "Edited",
            Id = new GeneralIdRef
            {
                Id = 1
            }
        };

        //Act & Assert
        Assert.ThrowsAsync<NotFoundException>(() => _formManager.EditFormTemplateAsync(auditResult, editForm, default));
    }

    [Test]
    public async Task EditForm_With3Version_SaveChangesAsync()
    {
        //Arrange
        var form = new FormTemplate
        {
            Guid = Guid.NewGuid(),
            Deleted = false,
            Id = 1,
            Name = "Test",
        };
        var formVersion = new FormTemplateVersion
        {
            Deleted = false,
            FormDefinition = "testttt",
            Id = 1,
            Guid = Guid.NewGuid(),
            TemplateId = 1,
            Template = form,
            Version = 1
        };
        var formVersionTwo = new FormTemplateVersion
        {
            Deleted = false,
            FormDefinition = "testttt",
            Id = 2,
            Guid = Guid.NewGuid(),
            TemplateId = 1,
            Template = form,
            Version = 2
        };
        var formVersionThree = new FormTemplateVersion
        {
            Deleted = false,
            FormDefinition = "testttt",
            Id = 3,
            Guid = Guid.NewGuid(),
            TemplateId = 1,
            Template = form,
            Version = 3
        };
        var editForm = new EditFormTemplate
        {
            Definition = "EditedDef",
            Name = "Edited",
            Id = new GeneralIdRef
            {
                Id = 1
            }
        };
        form.Versions = [formVersionThree];
        _fakeformRepository.FormTemplateVersions.AddRange([formVersion, formVersionTwo, formVersionThree ]);
        _fakeformRepository.FormTemplates.Add(form);

        //Act
        await _formManager.EditFormTemplateAsync(auditResult, editForm, default);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(_fakeformRepository.FormTemplateVersions, Has.Count.EqualTo(4));
            Assert.That(_fakeformRepository.FormTemplateVersions[3].Version, Is.EqualTo(4));
            Assert.That(_fakeformRepository.FormTemplates[0].Name, Is.EqualTo("Edited"));
        });

    }

    [Test]
    public async Task EditForm_OnlyNameDosentCreateANewVersion()
    {
        //Arrange
        var editFormName = "SOmeeese";
        var form = new FormTemplate
        {
            Guid = Guid.NewGuid(),
            Deleted = false,
            Id = 1,
            Name = "Test",
        };
        var formVersion = new FormTemplateVersion
        {
            Deleted = false,
            FormDefinition = editFormName,
            Id = 1,
            Guid = Guid.NewGuid(),
            TemplateId = 1,
            Template = form
        };
        form.Versions = [ formVersion ];
        _fakeformRepository.FormTemplateVersions.Add(formVersion);
        _fakeformRepository.FormTemplates.Add(form);
        var editForm = new EditFormTemplate
        {
            Name = editFormName,
            Id = new GeneralIdRef
            {
                Id = 1
            }
        };

        //Act
        await _formManager.EditFormTemplateAsync(auditResult, editForm, default);

        //Asserts
        Assert.Multiple(() =>
        {
            Assert.That(form.Name, Is.EqualTo(editFormName));
            Assert.That(_fakeformRepository.FormTemplates, Has.Count.EqualTo(1));
        });
    }
}