using Hcs.Broker;
using Hcs.WebApp.Data.Hcs;
using Hcs.WebApp.Services;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

namespace Hcs.WebApp.BackgroundServices.ResultGetters.NsiCommon
{
    public class ExportNsiItemGetter_15_7_0_1(IClient client, IServiceScope scope, Operation operation) : ResultGetterBase(client, scope, operation)
    {
        public override async Task<bool> GetAsync()
        {
            var result = await client.NsiCommon.GetExportNsiItemResultAsync(operation.MessageGuid!);
            if (!result.Ready)
            {
                return false;
            }

            if (result.Success)
            {
                var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
                var registryService = scope.ServiceProvider.GetRequiredService<RegistryService>();

                using var context = headquartersService.GetNewContext();
                var executionStrategy = context.Database.CreateExecutionStrategy();
                await executionStrategy.ExecuteAsync(async () =>
                {
                    using var transaction = await context.Database.BeginTransactionAsync();
                    try
                    {
                        var registry = await registryService.GetRegistryByOperationIdAsync(context, operation.Id, true);
                        registry.SyncedAt = DateTime.UtcNow;
                        registry.Elements?.Clear();
                        await context.SaveChangesAsync();

                        registry.Elements ??= [];

                        foreach (var element in result.Result!.NsiElement)
                        {
                            var registryElement = new RegistryElement()
                            {
                                Code = element.Code,
                                GUID = element.GUID,
                                Json = JsonConvert.SerializeObject(element)
                            };
                            registry.Elements.Add(registryElement);
                        }
                        await context.SaveChangesAsync();

                        await headquartersService.SetOperationEndedAsync(context, operation.Id);

                        await transaction.CommitAsync();
                    }
                    catch
                    {
                        await transaction.RollbackAsync();

                        throw;
                    }
                });

                return true;
            }

            throw Failure(result.ErrorMessage);
        }
    }
}
