using Ablera.Serdica.Microservice.Consumer.Attributes;
using Ablera.Serdica.Microservice.Consumer.Contracts.Asynchronous;
using Ablera.Serdica.Authority.Services;
using System.Threading.Tasks;
using Ablera.Serdica.DBModels.Serdica;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using Ablera.Serdica.Authentication.Constants;
using Ablera.Serdica.Extensions.RabbitMQ.Listeners;
using Ablera.Serdica.Extensions.RabbitMQ.Contracts;

namespace Ablera.Serdica.NotificationService.Endpoints;

public record UserBranchesResponse
{
    public long Id { get; init; }
    public long BranchId { get; init; }
    public required string BranchCode { get; init; }
    public required string BranchName { get; init; }
    public long? ReportTo { get; init; }
    public string? AgentCode { get; init; }
}

[Command("users_get_user_branches", timeoutInSeconds: 10, methodName: "GET", allowedRoles: [SerdicaClaims.IsAuthenticated])]
public class UserBranchesEndpoint(
    IEndpointRequestMessageProvider requestMessageProvider,
    SerdicaDbContext dbContext)
        : IEndpointWithNoRequest<UserBranchesResponse[]>
{
    public async Task<UserBranchesResponse[]> ConsumeAsync()
    {
        var items = await dbContext
            .IcUsers
            .Include(x => x.IcBranch)
            .Include(x => x.UserAccount)
            .Where(x => x.UserAccount.UserGuid == requestMessageProvider.RequestMessage.UserId)
            .ToListAsync();
        var srCustIds = items.Where(x => x.IcBranch != null)
            .Select(x => x.IcBranch.SrCustId)
            .ToArray();
        var branchNames = await dbContext
            .CCusts
            .Include(x => x.CCompany)
            .Where(x => srCustIds.Contains(x.SrCustId))
            .Where(x => x.CCompany != null)
            .ToDictionaryAsync(x => x.SrCustId, x => x.CCompany.CompName);

        var dtos = items.Select(x => new UserBranchesResponse
        {
            AgentCode = x.AgentCode,
            BranchId = x.IcBranchId.HasValue == false ? 0 : (long)x.IcBranchId,
            ReportTo = (long?)x.ReportTo,
            BranchCode = x.IcBranch.BranchCode,
            BranchName = branchNames.ContainsKey(x.IcBranch.SrCustId ?? 0) 
                ? branchNames[x.IcBranch.SrCustId ?? 0] 
                : x.IcBranch.BranchCode,
            Id = (long)x.IcUserId,
        });

        return dtos.ToArray();
    }
}