using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Indotalent.Features.Account.TenantSelection.Cqrs;

public record GetTenantsQuery(string UserId) : IRequest<List<TenantLookupDto>>;

public class TenantLookupDto
{
    public string TenantId { get; set; } = string.Empty;
    public string TenantName { get; set; } = string.Empty;
    public string? Description { get; set; }
}

public class GetTenantsHandler : IRequestHandler<GetTenantsQuery, List<TenantLookupDto>>
{
    private readonly AppDbContext _context;

    public GetTenantsHandler(AppDbContext context)
    {
        _context = context;
    }

    public async Task<List<TenantLookupDto>> Handle(GetTenantsQuery request, CancellationToken cancellationToken)
    {
        return await _context.Set<TenantUser>()
            .IgnoreQueryFilters()
            .Where(tu => tu.UserId == request.UserId && tu.IsActive)
            .Select(tu => new TenantLookupDto
            {
                TenantId = tu.TenantId ?? string.Empty,
                TenantName = tu.Tenant != null ? (tu.Tenant.Name ?? "Unknown") : "Unknown",
                Description = tu.Tenant != null ? (tu.Tenant.Description ?? "") : ""
            })
            .ToListAsync(cancellationToken);
    }
}

public record ConfirmTenantRequest(string TenantId);
public record ConfirmTenantResponse(bool Success, string Message);
public record ConfirmTenantCommand(string UserId, ConfirmTenantRequest Data) : IRequest<ConfirmTenantResponse>;

public class ConfirmTenantHandler : IRequestHandler<ConfirmTenantCommand, ConfirmTenantResponse>
{
    private readonly AppDbContext _context;

    public ConfirmTenantHandler(AppDbContext context)
    {
        _context = context;
    }

    public async Task<ConfirmTenantResponse> Handle(ConfirmTenantCommand request, CancellationToken cancellationToken)
    {
        var hasAccess = await _context.Set<TenantUser>()
            .IgnoreQueryFilters()
            .AnyAsync(tu => tu.UserId == request.UserId && tu.TenantId == request.Data.TenantId && tu.IsActive, cancellationToken);

        if (!hasAccess)
        {
            return new ConfirmTenantResponse(false, "Access denied to the selected organization.");
        }

        return new ConfirmTenantResponse(true, "Tenant authorized.");
    }
}