using IdokladSdk.Enums;

namespace Idoklad.Configuration;

/// <summary>
/// Service configuration resolved from environment variables.
///
/// Mirrors the structure used by the sibling microsoft-365-service (config.py): non-secret
/// configuration and credential defaults live in environment variables. Per-request callers
/// can override the credential values through request headers (see
/// <see cref="Credentials.RequestCredentialsProvider"/>).
/// </summary>
public sealed class IdokladSettings
{
    public string AppName { get; init; } = GetEnv("APP_NAME", "iDoklad Service");
    public string AppVersion { get; init; } = GetEnv("APP_VERSION", "1.0.0");
    public string RootPath { get; init; } = GetEnv("ROOT_PATH", string.Empty);

    /// <summary>Default iDoklad OAuth2 client id (client credentials flow).</summary>
    public string ClientId { get; init; } = GetEnv("IDOKLAD_CLIENT_ID", string.Empty);

    /// <summary>Default iDoklad OAuth2 client secret (client credentials flow).</summary>
    public string ClientSecret { get; init; } = GetEnv("IDOKLAD_CLIENT_SECRET", string.Empty);

    /// <summary>Default iDoklad application id from the developer portal (required by client credentials flow).</summary>
    public string ApplicationId { get; init; } = GetEnv("IDOKLAD_APPLICATION_ID", string.Empty);

    /// <summary>Optional custom iDoklad API base url (defaults to the SDK production url when empty).</summary>
    public string ApiUrl { get; init; } = GetEnv("IDOKLAD_API_URL", string.Empty);

    /// <summary>Optional custom Identity Server token url (defaults to the SDK production url when empty).</summary>
    public string IdentityServerUrl { get; init; } = GetEnv("IDOKLAD_IDENTITY_URL", string.Empty);

    /// <summary>Default response language for the iDoklad API (Cz, Sk, En). Defaults to Cz.</summary>
    public Language Language { get; init; } = ParseLanguage(GetEnv("IDOKLAD_LANGUAGE", "Cz"));

    public int RequestTimeoutSeconds { get; init; } = ParseInt(GetEnv("IDOKLAD_REQUEST_TIMEOUT_SECONDS", "100"), 100);

    /// <summary>True when both custom urls are configured (e.g. for a sandbox environment).</summary>
    public bool HasCustomUrls => !string.IsNullOrWhiteSpace(ApiUrl) && !string.IsNullOrWhiteSpace(IdentityServerUrl);

    /// <summary>True when the default credential triplet is fully configured via environment variables.</summary>
    public bool HasDefaultCredentials =>
        !string.IsNullOrWhiteSpace(ClientId)
        && !string.IsNullOrWhiteSpace(ClientSecret)
        && !string.IsNullOrWhiteSpace(ApplicationId);

    private static string GetEnv(string name, string fallback)
    {
        var value = Environment.GetEnvironmentVariable(name);
        return string.IsNullOrWhiteSpace(value) ? fallback : value;
    }

    private static int ParseInt(string value, int fallback) =>
        int.TryParse(value, out var parsed) && parsed > 0 ? parsed : fallback;

    private static Language ParseLanguage(string value) =>
        Enum.TryParse<Language>(value, ignoreCase: true, out var parsed) ? parsed : Language.Cz;
}
