using Microsoft.Extensions.Configuration;
using System.Net;
using Tiku.Application.Security;

namespace Tiku.Api.Options;

public static class OptionsValidation
{
    public static string ResolveDatabaseConnectionString(
        IConfiguration configuration,
        bool isDevelopment)
    {
        var connectionString =
            configuration.GetConnectionString("Database") ??
            configuration["DATABASE_URL"];
        if (!string.IsNullOrWhiteSpace(connectionString))
        {
            return connectionString;
        }

        if (isDevelopment)
        {
            return $"Host=localhost;Database=tiku;Username={Environment.UserName}";
        }

        throw new InvalidOperationException(
            "Database connection is required outside Development. Configure ConnectionStrings:Database or DATABASE_URL.");
    }

    public static bool BeValidJwtOptions(JwtOptions options, bool isProduction)
    {
        return JwtOptions.BeValid(options, isProduction);
    }

    public static bool BeValidCorsOptions(CorsOptions options)
    {
        if (options.AllowCredentials && options.AllowedOrigins.Length == 0)
        {
            return false;
        }

        return options.AllowedOrigins.All(IsHttpOrigin);
    }

    public static bool BeValidTenantResolutionOptions(
        TenantResolutionOptions options,
        IConfiguration configuration,
        bool isProduction)
    {
        if (!isProduction)
        {
            return true;
        }

        var platformHosts = options.PlatformHosts
            .Where(host => !string.IsNullOrWhiteSpace(host))
            .Select(host => host.Trim())
            .ToArray();
        var hasFormalHost = platformHosts.Any(host =>
            !string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase) &&
            !string.Equals(host, "127.0.0.1", StringComparison.OrdinalIgnoreCase) &&
            !string.Equals(host, "::1", StringComparison.OrdinalIgnoreCase));
        var allowedHosts = configuration["AllowedHosts"];
        return hasFormalHost &&
               options.TrustedProxyAddresses.Any(address => IPAddress.TryParse(address, out _)) &&
               !string.IsNullOrWhiteSpace(allowedHosts) &&
               !allowedHosts.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
                   .Contains("*", StringComparer.Ordinal);
    }

    private static bool IsHttpOrigin(string origin)
    {
        return Uri.TryCreate(origin, UriKind.Absolute, out var uri) &&
               (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) &&
               string.IsNullOrEmpty(uri.PathAndQuery.Trim('/'));
    }
}
