using LiteCqrs;
using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;

namespace TeleWave.Application.Programming.Templates.Junctions;

public sealed class ListJunctionsQueryHandler(IAppDbContext dbContext)
    : IQueryHandler<ListJunctionsQuery, IReadOnlyList<JunctionTemplateDto>>
{
    public async Task<IReadOnlyList<JunctionTemplateDto>> Handle(
        ListJunctionsQuery query,
        CancellationToken cancellationToken
    )
    {
        var junctions = await dbContext
            .JunctionTemplates.AsNoTracking()
            .Include(j => j.Elements)
            .Where(j => j.ChannelId == query.ChannelId)
            .OrderBy(j => j.Name)
            .ToListAsync(cancellationToken);

        // Имена групп и блоков заставок резолвим одним проходом — редактор показывает их сразу.
        var groupIds = junctions
            .SelectMany(j => j.Elements)
            .Select(e => e.GroupId)
            .Where(id => id is not null)
            .Select(id => id!.Value)
            .Distinct()
            .ToList();
        var groupNames = await dbContext
            .Groups.AsNoTracking()
            .Where(g => groupIds.Contains(g.Id))
            .ToDictionaryAsync(g => g.Id, g => g.Name, cancellationToken);

        var bumperNames = await dbContext
            .Channels.AsNoTracking()
            .Where(c => c.Id == query.ChannelId)
            .SelectMany(c => c.BumperTemplates)
            .ToDictionaryAsync(t => t.Id, t => t.Name, cancellationToken);

        return junctions
            .Select(j => new JunctionTemplateDto(
                j.Id,
                j.Name,
                j.Elements.OrderBy(e => e.Position)
                    .Select(e => new JunctionElementDto(
                        e.Id,
                        e.Position,
                        e.Kind,
                        e.GroupId,
                        e.GroupId is { } gid && groupNames.TryGetValue(gid, out var gname)
                            ? gname
                            : null,
                        e.BumperTemplateId,
                        e.BumperTemplateId is { } bid && bumperNames.TryGetValue(bid, out var bname)
                            ? bname
                            : null,
                        e.AmountMode,
                        e.AmountValue,
                        e.IsRequired,
                        JunctionConditions.FromJson(e.ConditionsJson)
                    ))
                    .ToList()
            ))
            .ToList();
    }
}
