namespace TrackQrApi.Features.Assets.Services;

public interface IAssetStorageService
{
    Task<string> StoreAsync(Stream stream, string filename, string contentType);
    Task<(Stream Stream, string ContentType)?> GetAsync(string storageKey);
    Task DeleteAsync(string storageKey);
    string GetPublicUrl(string storageKey, HttpContext context);
}

public class LocalAssetStorageService : IAssetStorageService
{
    private readonly string _basePath;
    private readonly ILogger<LocalAssetStorageService> _logger;

    public LocalAssetStorageService(IConfiguration configuration, ILogger<LocalAssetStorageService> logger)
    {
        _logger = logger;
        _basePath = configuration["Storage:LocalPath"] ?? Path.Combine(Directory.GetCurrentDirectory(), "uploads");

        // Ensure directory exists
        if (!Directory.Exists(_basePath)) Directory.CreateDirectory(_basePath);
    }

    public async Task<string> StoreAsync(Stream stream, string filename, string contentType)
    {
        // Generate unique storage key
        var extension = Path.GetExtension(filename);
        var storageKey = $"{Guid.NewGuid()}{extension}";
        var filePath = Path.Combine(_basePath, storageKey);

        await using var fileStream = new FileStream(filePath, FileMode.Create);
        await stream.CopyToAsync(fileStream);

        _logger.LogDebug("Stored asset at {FilePath}", filePath);

        return storageKey;
    }

    public Task<(Stream Stream, string ContentType)?> GetAsync(string storageKey)
    {
        var filePath = Path.Combine(_basePath, storageKey);

        if (!File.Exists(filePath)) return Task.FromResult<(Stream, string)?>(null);

        var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        var contentType = GetContentType(storageKey);

        return Task.FromResult<(Stream, string)?>((stream, contentType));
    }

    public Task DeleteAsync(string storageKey)
    {
        var filePath = Path.Combine(_basePath, storageKey);

        if (File.Exists(filePath))
        {
            File.Delete(filePath);
            _logger.LogDebug("Deleted asset at {FilePath}", filePath);
        }

        return Task.CompletedTask;
    }

    public string GetPublicUrl(string storageKey, HttpContext context)
    {
        var baseUrl = $"{context.Request.Scheme}://{context.Request.Host}";
        return $"{baseUrl}/assets/{storageKey}";
    }

    private static string GetContentType(string filename)
    {
        var extension = Path.GetExtension(filename).ToLowerInvariant();
        return extension switch
        {
            ".png" => "image/png",
            ".jpg" or ".jpeg" => "image/jpeg",
            ".gif" => "image/gif",
            ".webp" => "image/webp",
            ".svg" => "image/svg+xml",
            _ => "application/octet-stream"
        };
    }
}