using IWS5.Core.Enums;
using IWS5.Core.Models.Request;
using IWS5.DatabaseAccess.Interfaces;
using IWS5.DatabaseAccess.IwsDataContext;
using IWS5.DatabaseAccess.IwsDataModels;
using Microsoft.EntityFrameworkCore;
using Serilog;

namespace IWS5.DatabaseAccess.Repositories;

public class QueueRepository(GreenfieldPd2015Context context, ILogger logger)
    : IWSRepository<Atqueue>(context), IQueueRepository
{
    public async Task<IReadOnlyCollection<Atqueue>> GetAllowedQueues(ListQueuesRequest request)
    {
        logger.Information("Starting GetAllowedQueues for User {UserName} and ProcessId {ProcessId}", request.UserName,
            request.ProcessId);
        
        var allowedQueuesGuids = context.Atusers
            .AsNoTracking()
            .Where(user => user.UserName == request.UserName)
            .SelectMany(user => user.Parents.SelectMany(parent => parent.Atrights))
            .Where(right => right.ObjectType == (int)ObjectType.Queue && right.AllowRights == (int)ATRightAllowRight.UseQueue)
            .Select(right => right.ObjectGuid)
            .Distinct();

        var queuesQuery = context.Atqueues
            .AsNoTracking()
            .Include(e => e.Process)
            .Where(queue => allowedQueuesGuids.Contains(queue.ObjectId) &&
                            queue.ProcessId == request.ProcessId)
            .OrderBy(queue => queue.Queue)
            .Select(queue => new Atqueue
            {
                Id = queue.Id,
                Queue = queue.Queue,
                Alias = queue.Alias,
                ObjectId = queue.ObjectId,
                Signable = queue.Signable,
                Process = new AtprocessDefinition
                {
                    ProcessId = queue.Process.ProcessId,
                    ProcessName = queue.Process.ProcessName
                }
            });

        logger.Information("Generated SQL query: {Query}", queuesQuery.ToQueryString());

        var result = await queuesQuery.ToListAsync();

        logger.Information("Successfully retrieved {QueueCount} queues for User {UserName}", result.Count,
            request.UserName);

        return result.AsReadOnly();
    }
}