using TeleWave.Application.Common.Interfaces;

namespace TeleWave.Infrastructure.Media;

/// <summary>Скачивает изображение по URL через HTTP-клиент «metadata» и определяет расширение.</summary>
public sealed class ImageDownloader(IHttpClientFactory httpFactory) : IImageDownloader
{
    public async Task<DownloadedImage?> DownloadAsync(
        string url,
        CancellationToken cancellationToken
    )
    {
        // Пускаем только абсолютные http/https URL: URL приходит из ответа metadata-провайдера
        // (постеры TMDb/OMDb), и скомпрометированный/подменённый ответ не должен заставить сервер
        // дёрнуть file://, ftp:// или иную схему.
        if (
            !Uri.TryCreate(url, UriKind.Absolute, out var uri)
            || (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
        )
            return null;

        try
        {
            var client = httpFactory.CreateClient("metadata");
            using var response = await client.GetAsync(uri, cancellationToken);
            if (!response.IsSuccessStatusCode)
                return null;

            var ext = ExtensionFor(url, response.Content.Headers.ContentType?.MediaType);
            var bytes = await response.Content.ReadAsByteArrayAsync(cancellationToken);
            return bytes.Length == 0 ? null : new DownloadedImage(bytes, ext);
        }
        catch (Exception ex)
            when (ex is HttpRequestException or TaskCanceledException or IOException)
        {
            return null;
        }
    }

    private static string ExtensionFor(string url, string? mediaType) =>
        mediaType switch
        {
            "image/png" => ".png",
            "image/webp" => ".webp",
            "image/gif" => ".gif",
            "image/jpeg" => ".jpg",
            _ => Path.GetExtension(new Uri(url).AbsolutePath) is { Length: > 1 } e
                ? e.ToLowerInvariant()
                : ".jpg",
        };
}
