using System;
using System.Linq;
using Ablera.Serdica.Authentication.Models.Oidc;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace Ablera.Serdica.Authority.Services;

public class AuthenticationUrlBuilder(ILogger<AuthenticationUrlBuilder> logger, OidcJsonSettingsProvider oidcJsonSettingsProvider)
{
    public  string? BuildAuthenticationUrl(
        string clientId,
        string authenticationDelegateUrl,
        HttpRequest request)
    {
        var redirectUrls = oidcJsonSettingsProvider.Settings.RegisteredClients.Where(x => x.ClientId == clientId)
            .SelectMany(x => x.RedirectUris ?? [])
            .ToArray();
        if (redirectUrls.Length == 0)
        {
            logger.LogError($"No {nameof(RegisteredClient.RedirectUris)} configured for client with id {clientId}", clientId);
            return null;
        }

        string? redirectUrl = null;
        var refererHeader = request.Headers["Referer"].ToString();
        if (!string.IsNullOrEmpty(refererHeader) && redirectUrls.Any(x => refererHeader.StartsWith(x)))
        {
            var refererUri = new Uri(refererHeader);
            redirectUrl = $"{refererUri.Scheme}://{refererUri.Host}{(refererUri.IsDefaultPort ? "" : $":{refererUri.Port}")}{refererUri.AbsolutePath}";
        }
        if (redirectUrl == null)
        {
            redirectUrl = redirectUrls[0];
            logger.LogWarning("Unable to determine client url from headers. Will use default redirect url instead {issuerUrl}",
                redirectUrl);
        }

        var processedDelegateUrl = authenticationDelegateUrl
            .Replace("{{issuer_url}}", oidcJsonSettingsProvider.Settings.IssuerUrl)
            .Replace("{{redirect_url}}", redirectUrl ?? string.Empty);

        var authorizationConfirmUrl =
            $"{request.Scheme}://{request.Host}{request.Path}{request.QueryString}";

        var authenticationUrl = processedDelegateUrl + "&confirmUrl=" + Uri.EscapeDataString(authorizationConfirmUrl);
        return authenticationUrl;
    }
}