using Microsoft.Extensions.Options;
using OmsorgCore.Application.Abstractions;

namespace OmsorgCore.Infrastructure.Storage;

/// <summary>
/// Legt Dokument-Bytes auf dem Dateisystem unterhalb von Storage:DocumentsRootPath ab, unter
/// {EntityType}/{EntityId}/{DocumentId}{Extension} - EntityId/DocumentId sind Guids und
/// Extension kommt aus Path.GetExtension, kein Client-String fließt direkt in den Pfad ein
/// (kein Path-Traversal-Vektor).
/// </summary>
public class FileSystemDocumentStorage : IDocumentStorage
{
    private readonly string _rootPath;

    public FileSystemDocumentStorage(IOptions<StorageOptions> options)
    {
        _rootPath = Path.GetFullPath(options.Value.DocumentsRootPath);
    }

    public async Task<string> SaveAsync(string entityType, Guid entityId, Guid documentId, string originalFileName, Stream content, CancellationToken cancellationToken = default)
    {
        var extension = Path.GetExtension(originalFileName);
        var relativePath = Path.Combine(entityType, entityId.ToString(), $"{documentId}{extension}");
        var fullPath = Path.Combine(_rootPath, relativePath);

        Directory.CreateDirectory(Path.GetDirectoryName(fullPath)!);

        await using var fileStream = new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
        await content.CopyToAsync(fileStream, cancellationToken);

        return relativePath;
    }

    public Task<Stream> OpenReadAsync(string storageKey, CancellationToken cancellationToken = default)
    {
        var fullPath = Path.Combine(_rootPath, storageKey);
        Stream stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
        return Task.FromResult(stream);
    }
}
