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

namespace Tiku.Infrastructure.Auth;

public sealed partial class AuthService
{
    public async Task<AuthenticationResult> LoginWithSmsAsync(
        SmsLoginRequest request,
        CancellationToken cancellationToken = default)
    {
        var phone = SmsCodeHashing.NormalizePhone(request.Phone);
        var user = await dbContext.Users
            .SingleOrDefaultAsync(entity => entity.Phone == phone, cancellationToken);

        try
        {
            if (!request.TenantId.HasValue) throw new InvalidCredentialsException("tenant_required_for_sms");
            await smsVerificationService.VerifyCodeAsync(
                request.TenantId.Value,
                phone,
                SmsPurpose.Login,
                request.Code,
                cancellationToken);
        }
        catch (InvalidCredentialsException exception)
        {
            await AddLoginEventAsync(
                request.TenantId,
                user?.Id,
                SmsProvider,
                phone,
                AuthLoginResult.Failed,
                exception.Code,
                request.IpAddress,
                request.UserAgent,
                cancellationToken);
            throw;
        }

        if (user is null)
        {
            await AddLoginEventAsync(
                request.TenantId,
                null,
                SmsProvider,
                phone,
                AuthLoginResult.Failed,
                "user_not_found",
                request.IpAddress,
                request.UserAgent,
                cancellationToken);
            throw new InvalidCredentialsException();
        }

        return await CompleteSuccessfulLoginAsync(
            request.Realm,
            request.TenantId,
            user,
            SmsProvider,
            phone,
            request.IpAddress,
            request.UserAgent,
            cancellationToken);
    }
}