namespace Sonex.Services.ImageSync;

internal sealed class ImageSyncOptions
{
    private static readonly ImageSize[] DefaultSizes =
    [
        new(64, 64),
        new(128, 128),
        new(250, 250)
    ];

    private static readonly HashSet<string> DefaultExtensions =
        new(StringComparer.OrdinalIgnoreCase)
        {
            ".jpg",
            ".jpeg",
            ".png",
            ".bmp",
            ".gif",
            ".tif",
            ".tiff"
        };

    public required string SourceRoot { get; init; }
    public required string DestinationRoot { get; init; }
    public string SourceUserName { get; set; } = string.Empty;
    public string SourcePassword { get; set; } = string.Empty;

    public required string DbHost { get; init; }
    public int DbPort { get; init; }
    public required string DbDatabase { get; init; }
    public string DbUserName { get; set; } = string.Empty;
    public string DbPassword { get; set; } = string.Empty;
    public int DbTimeout { get; init; }
    public int DbCommandTimeout { get; init; }
    public bool DbPooling { get; init; }
    public int DbMinPoolSize { get; init; }
    public int DbMaxPoolSize { get; init; }
    public bool DbIncludeErrorDetail { get; init; }

    public bool UseWatcher { get; init; }
    public bool DeleteMissingFiles { get; init; }
    public int ScanIntervalSeconds { get; init; }
    public int WatcherDebounceMilliseconds { get; init; }
    public int StableFileDelayMilliseconds { get; init; }
    public int StableFileChecks { get; init; }
    public IReadOnlyList<ImageSize> Sizes { get; init; } = [];
    public HashSet<string> SupportedExtensions { get; init; } = new(StringComparer.OrdinalIgnoreCase);

    public bool SourceRequiresCredentials =>
        SourceRoot.StartsWith(@"\\", StringComparison.Ordinal) &&
        !string.IsNullOrWhiteSpace(SourceUserName);

    public static ImageSyncOptions Load()
    {
        string defaultDestinationRoot = Path.Combine(AppContext.BaseDirectory, "images");

        return new ImageSyncOptions
        {
            SourceRoot = NormalizePath(Config.GetStringValue("SourceRoot", @"\\x6\AfbeeldingenWeb\Afbeeldingen")),
            DestinationRoot = NormalizePath(Config.GetStringValue("DestinationRoot", defaultDestinationRoot)),
            SourceUserName = Config.GetStringValue("SourceUserName", ""),
            SourcePassword = Config.GetStringValue("SourcePassword", ""),
            DbHost = Config.GetStringValue("DB_HOST", "X-WEB-TEST"),
            DbPort = Config.GetIntValue("DB_PORT", 5432),
            DbDatabase = Config.GetStringValue("DB_DATA_BASE", "sonex"),
            DbUserName = Config.GetStringValue("DB_USER_NAME", ""),
            DbPassword = Config.GetStringValue("DB_PASSWORD", ""),
            DbTimeout = 15,
            DbCommandTimeout = 30,
            DbPooling = true,
            DbMinPoolSize = 0,
            DbMaxPoolSize = 100,
            DbIncludeErrorDetail = true,
            UseWatcher = true,
            DeleteMissingFiles = true,
            ScanIntervalSeconds = Config.GetIntValue("Scan_Interval_Seconds", 300),
            WatcherDebounceMilliseconds = Config.GetIntValue("Watcher_Debounce_Milliseconds", 1500),
            StableFileDelayMilliseconds = Config.GetIntValue("Stable_File_Delay_Milliseconds", 1),
            StableFileChecks = Config.GetIntValue("Stable_File_Checks", 3),
            Sizes = DefaultSizes,
            SupportedExtensions = new HashSet<string>(DefaultExtensions, StringComparer.OrdinalIgnoreCase)
        };
    }

    private static string NormalizePath(string path)
    {
        string value = (path ?? string.Empty).Trim().Trim('"');
        if (string.IsNullOrWhiteSpace(value))
            return string.Empty;

        if (value.StartsWith(@"\\", StringComparison.Ordinal))
            return value.TrimEnd('\\', '/');

        return Path.GetFullPath(value)
            .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
    }

}
