using Microsoft.Extensions.Configuration;
using Microsoft.Identity.Client;
using UniVerse.Application.Interfaces;
using UniVerse.Domain.Exceptions;

namespace UniVerse.Infrastructure.ExternalServices;

public class MicrosoftAuthClient : IMicrosoftAuthClient
{
    private readonly IConfiguration _config;

    public MicrosoftAuthClient(IConfiguration config)
    {
        _config = config;
    }

    public async Task<MicrosoftTokenResult> ExchangeAuthorizationCodeAsync(
        string authorizationCode,
        string redirectUri,
        CancellationToken cancellationToken = default)
    {
        var tenantId = _config["AzureAd:TenantId"];
        var clientId = _config["AzureAd:ClientId"];
        var clientSecret = _config["AzureAd:ClientSecret"];
        var instance = _config["AzureAd:Instance"] ?? "https://login.microsoftonline.com/";

        if (string.IsNullOrWhiteSpace(tenantId)
            || string.IsNullOrWhiteSpace(clientId)
            || string.IsNullOrWhiteSpace(clientSecret))
            throw new UnauthorizedException("Аутентификация Microsoft не настроена (AzureAd:TenantId/ClientId/ClientSecret).");

        var authority = $"{instance.TrimEnd('/')}/{tenantId}";

        var app = ConfidentialClientApplicationBuilder.Create(clientId)
            .WithClientSecret(clientSecret)
            .WithAuthority(new Uri(authority))
            .WithRedirectUri(redirectUri)
            .Build();

        try
        {
            var result = await app.AcquireTokenByAuthorizationCode(["User.Read"], authorizationCode)
                .ExecuteAsync(cancellationToken);

            return new MicrosoftTokenResult(result.IdToken);
        }
        catch (MsalException ex)
        {
            throw new UnauthorizedException($"Ошибка аутентификации Microsoft: {ex.Message}");
        }
    }
}
