using Microsoft.Extensions.Configuration;

namespace ROLAC.API.Services.Storage;

public class LocalDiskFileStorage : IFileStorage
{
    private readonly string _root;

    public LocalDiskFileStorage(IConfiguration config)
    {
        var configured = config["Storage:LocalRoot"] ?? "App_Data/storage";
        _root = Path.IsPathRooted(configured)
            ? configured
            : Path.Combine(Directory.GetCurrentDirectory(), configured);
        Directory.CreateDirectory(_root);
    }

    private string Resolve(string relativePath)
    {
        if (string.IsNullOrWhiteSpace(relativePath))
            throw new ArgumentException("relativePath is required.", nameof(relativePath));

        var normalized = relativePath.Replace('\\', '/').TrimStart('/');
        var full = Path.GetFullPath(Path.Combine(_root, normalized));
        var rootFull = Path.GetFullPath(_root) + Path.DirectorySeparatorChar;
        if (!full.StartsWith(rootFull, StringComparison.Ordinal))
            throw new ArgumentException("Path escapes storage root.", nameof(relativePath));
        return full;
    }

    public async Task<string> SaveAsync(Stream content, string relativePath, CancellationToken ct = default)
    {
        var full = Resolve(relativePath);
        Directory.CreateDirectory(Path.GetDirectoryName(full)!);
        await using var file = File.Create(full);
        await content.CopyToAsync(file, ct);
        return relativePath.Replace('\\', '/').TrimStart('/');
    }

    public Task<Stream?> OpenReadAsync(string relativePath, CancellationToken ct = default)
    {
        var full = Resolve(relativePath);
        Stream? result = File.Exists(full) ? File.OpenRead(full) : null;
        return Task.FromResult(result);
    }

    public Task DeleteAsync(string relativePath, CancellationToken ct = default)
    {
        var full = Resolve(relativePath);
        if (File.Exists(full)) File.Delete(full);
        return Task.CompletedTask;
    }
}
