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

namespace e_suite.Modules.FormsManagerUnitTests.FormsManagerUnitTests;

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

    [Test]
    public Task EditFormInstanceAsync_FormInstanceNotFound_ThrowsException()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails();
        var editFormInstance = new EditFormInstance
        {
            FormInstanceId = new GeneralIdRef
            {
                Guid = new Guid("c882cb17-22e6-4470-a402-fe9d0b18d292")
            }
        };


        //Assert
        var result = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            //Act
            await _formManager.EditFormInstanceAsync(auditUserDetails, editFormInstance, CancellationToken.None);
        });

        Assert.That(result, Is.Not.Null);
        Assert.That(result!.Message, Is.EqualTo("FormInstance not found"));
        return Task.CompletedTask;
    }

    [Test]
    public Task EditFormInstanceAsync_TemplateNotFound_ThrowsException()
    {
        //Arrange
        var formTemplateVersion = new FormTemplateVersion()
        {
            Guid = new Guid("8a9bd69b-6da0-4b56-a49a-0634f270051c"),
            Id = 6244
        };

        var formInstance = new FormInstance
        {
            Guid = new Guid("e706f520-b0b0-48f9-b937-74e7588a74b9"),
            Id = 5644,
            FormTemplateVersion = formTemplateVersion,
            FormTemplateVersionId = formTemplateVersion.Id
        };

        _fakeformRepository.FormInstances.Add(formInstance);

        var auditUserDetails = new AuditUserDetails();
        var editFormInstance = new EditFormInstance
        {
            FormInstanceId = new GeneralIdRef
            {
                Guid = formInstance.Guid
            },
            TemplateId = new GeneralIdRef
            {
                Guid = new Guid("a81a688b-be8d-4154-af0e-d2de8e431cb9")
            },
            Version = 10
        };

        //Assert
        var result = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            //Act
            await _formManager.EditFormInstanceAsync(auditUserDetails, editFormInstance, CancellationToken.None);
        });

        Assert.That(result, Is.Not.Null);
        Assert.That(result!.Message, Is.EqualTo("Template not found"));
        return Task.CompletedTask;
    }

    [Test]
    public Task EditFormInstanceAsync_TemplateVersionNotFound_ThrowsException()
    {
        //Arrange
        var formTemplate = new FormTemplate
        {
            Guid = new Guid("5ea17325-f16b-4e58-a6a4-a50185b7ffd9"),
            Id = 6564
        };

        var formTemplateVersion = new FormTemplateVersion()
        {
            Guid = new Guid("b25d2d69-e14c-4940-b6e9-acb1960796ab"),
            Id = 94237,
            Version = 20
        };

        formTemplate.Versions.Add(formTemplateVersion);

        var formInstance = new FormInstance
        {
            Guid = new Guid("e706f520-b0b0-48f9-b937-74e7588a74b9"),
            Id = 5644,
            FormTemplateVersion = formTemplateVersion,
            FormTemplateVersionId = formTemplateVersion.Id
        };

        _fakeformRepository.FormTemplates.Add(formTemplate);
        _fakeformRepository.FormTemplateVersions.Add(formTemplateVersion);
        _fakeformRepository.FormInstances.Add(formInstance);

        var auditUserDetails = new AuditUserDetails();
        var editFormInstance = new EditFormInstance
        {
            FormInstanceId = new GeneralIdRef
            {
                Guid = formInstance.Guid
            },
            TemplateId = new GeneralIdRef
            {
                Guid = formTemplate.Guid
            },
            Version = 10
        };

        //Assert
        var result = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            //Act
            await _formManager.EditFormInstanceAsync(auditUserDetails, editFormInstance, CancellationToken.None);
        });

        Assert.That(result, Is.Not.Null);
        Assert.That(result!.Message, Is.EqualTo("Version not found"));
        return Task.CompletedTask;
    }

    [Test]
    public async Task EditFormInstanceAsync_VersionFound_SavesChanages()
    {
        //Arrange
        var formTemplate = new FormTemplate
        {
            Guid = new Guid("5ea17325-f16b-4e58-a6a4-a50185b7ffd9"),
            Id = 6564
        };

        var formTemplateVersion = new FormTemplateVersion()
        {
            Guid = new Guid("b25d2d69-e14c-4940-b6e9-acb1960796ab"),
            Id = 94237,
            Version = 20
        };

        formTemplate.Versions.Add(formTemplateVersion);

        var formInstance = new FormInstance
        {
            Guid = new Guid("e706f520-b0b0-48f9-b937-74e7588a74b9"),
            Id = 5644,
            FormTemplateVersion = formTemplateVersion,
            FormTemplateVersionId = formTemplateVersion.Id,
            FormFields = []
        };

        _fakeformRepository.FormTemplates.Add(formTemplate);
        _fakeformRepository.FormTemplateVersions.Add(formTemplateVersion);
        _fakeformRepository.FormInstances.Add(formInstance);

        var auditUserDetails = new AuditUserDetails();
        var editFormInstance = new EditFormInstance
        {
            FormInstanceId = new GeneralIdRef
            {
                Guid = formInstance.Guid
            },
            TemplateId = new GeneralIdRef
            {
                Guid = formTemplate.Guid
            },
            Version = 20
        };

        //Act
        await _formManager.EditFormInstanceAsync(auditUserDetails, editFormInstance, CancellationToken.None);

        //Assert
        Assert.That(_fakeformRepository.SaveCustomFieldValuesCalled, Is.True);
    }
}