using Microsoft.EntityFrameworkCore;
using Tiku.Application.Auth;
using Tiku.Domain.Tenancy;
using Tiku.Infrastructure.Persistence;

namespace Tiku.Infrastructure.Auth;

internal sealed class CurrentIdentityQueryService(TikuDbContext dbContext) : ICurrentIdentityQueryService
{
    public async Task<CurrentUserProfile?> GetUserAsync(
        Guid userId,
        CancellationToken cancellationToken = default)
    {
        var user = await dbContext.Users.AsNoTracking()
            .Where(item => item.Id == userId)
            .Select(item => new { item.Id, item.Phone, item.Email, item.Name })
            .SingleOrDefaultAsync(cancellationToken);
        if (user is null) return null;

        var memberships = await dbContext.TenantMemberships.AsNoTracking()
            .Where(item => item.UserId == userId && item.Status == MembershipStatus.Active)
            .Join(
                dbContext.Tenants.AsNoTracking(),
                membership => membership.TenantId,
                tenant => tenant.Id,
                (membership, tenant) => new CurrentUserTenant(
                    tenant.Id,
                    tenant.Name,
                    tenant.Slug,
                    membership.Role,
                    membership.Status))
            .ToArrayAsync(cancellationToken);

        return new CurrentUserProfile(user.Id, user.Phone, user.Email, user.Name, memberships);
    }

    public Task<CurrentTenantMembership?> GetTenantMembershipAsync(
        Guid userId,
        Guid tenantId,
        CancellationToken cancellationToken = default)
    {
        return dbContext.TenantMemberships.AsNoTracking()
            .Where(item =>
                item.UserId == userId &&
                item.TenantId == tenantId &&
                item.Status == MembershipStatus.Active)
            .Join(
                dbContext.Tenants.AsNoTracking(),
                membership => membership.TenantId,
                tenant => tenant.Id,
                (membership, tenant) => new CurrentTenantMembership(
                    tenant.Id,
                    tenant.Name,
                    tenant.Slug,
                    tenant.Status,
                    membership.Role))
            .SingleOrDefaultAsync(cancellationToken);
    }
}