using Hcs.WebApp.Data.Hcs;
using Microsoft.EntityFrameworkCore;

namespace Hcs.WebApp.Services
{
    public class RegistryService(IDbContextFactory<HcsDbContext> factory) : HcsServiceBase(factory)
    {
        public async Task<int> GetRegistryCountAsync(HcsDbContext context, bool isCommon)
        {
            return await context.Registries.CountAsync(x => x.IsCommon == isCommon);
        }

        public async Task<IEnumerable<Registry>> GetAllRegistriesAsync(bool isCommon)
        {
            using var context = GetNewContext();
            return await (from registry in context.Registries
                          where registry.IsCommon == isCommon
                          select registry).ToListAsync();
        }

        public async Task<Registry> GetRegistryByOperationIdAsync(int operationId)
        {
            using var context = GetNewContext();
            return await GetRegistryByOperationIdAsync(context, operationId);
        }

        public async Task<Registry> GetRegistryByOperationIdAsync(HcsDbContext context, int operationId, bool includeElements = false)
        {
            if (includeElements)
            {
                return await context.Registries
                    .Include(x => x.Elements)
                    .SingleAsync(x => x.LastSyncOperationId == operationId);
            }
            return await context.Registries.SingleAsync(x => x.LastSyncOperationId == operationId);
        }

        public async Task<IEnumerable<Registry>> GetRegistriesByOperationIdAsync(int operationId)
        {
            using var context = GetNewContext();
            return await (from registry in context.Registries
                          where registry.LastSyncOperationId == operationId
                          select registry).ToListAsync();
        }

        public async Task SetOperationsToRegistriesAsync(HcsDbContext context, bool isCommon, IEnumerable<Operation> operations)
        {
            var queue = new Queue<Operation>(operations);
            await context.Registries.ForEachAsync(x =>
            {
                if (x.IsCommon == isCommon)
                {
                    x.LastSyncOperationId = queue.Dequeue().Id;
                }
            });
            await context.SaveChangesAsync();
        }

        public async Task<ICollection<RegistryElement>> GetRegistryElementsAsync(Guid registryId)
        {
            using var context = GetNewContext();
            return await context.Elements.Where(x => x.RegistryId == registryId).ToListAsync();
        }

        public async Task<string?> GetRegistryElementJsonAsync(Guid registryElementId)
        {
            using var context = GetNewContext();
            return await (from registryElement in  context.Elements
                          where registryElement.Id == registryElementId
                          select registryElement.Json).FirstOrDefaultAsync();
        }
    }
}
