using TeleWave.Application.Common.Interfaces;

namespace TeleWave.Infrastructure.Media;

/// <summary>
/// Файловое хранилище звука блоков заставок: bumpers/{templateId}/audio{ext}. На блок — не более
/// одного файла (при загрузке старый удаляется). Фон-картинка блока хранится в общем реестре.
/// </summary>
public sealed class BumperTemplateStorage(MediaPathResolver paths) : IBumperTemplateStorage
{
    private const string Audio = "audio";

    public Task SaveAudioAsync(
        Guid templateId,
        string extension,
        Stream content,
        CancellationToken cancellationToken
    ) => SaveAsync(templateId, Audio, extension, content, cancellationToken);

    public Task DeleteAudioAsync(Guid templateId, CancellationToken cancellationToken)
    {
        DeleteKind(templateId, Audio);
        return Task.CompletedTask;
    }

    public Task DeleteTemplateAsync(Guid templateId, CancellationToken cancellationToken) =>
        Task.Run(
            () =>
            {
                var dir = paths.BumperTemplateDir(templateId);
                if (Directory.Exists(dir))
                    Directory.Delete(dir, recursive: true);
            },
            cancellationToken
        );

    public string? AudioPath(Guid templateId, string? extension) =>
        ResolvePath(templateId, Audio, extension);

    private async Task SaveAsync(
        Guid templateId,
        string kind,
        string extension,
        Stream content,
        CancellationToken cancellationToken
    )
    {
        var dir = paths.BumperTemplateDir(templateId);
        Directory.CreateDirectory(dir);
        RemoveExisting(dir, kind);

        var path = paths.BumperTemplateFilePath(templateId, kind, NormalizeExtension(extension));
        await using var fs = File.Create(path);
        await content.CopyToAsync(fs, cancellationToken);
    }

    private void DeleteKind(Guid templateId, string kind)
    {
        var dir = paths.BumperTemplateDir(templateId);
        if (Directory.Exists(dir))
            RemoveExisting(dir, kind);
    }

    private string? ResolvePath(Guid templateId, string kind, string? extension)
    {
        if (string.IsNullOrWhiteSpace(extension))
            return null;
        var path = paths.BumperTemplateFilePath(templateId, kind, NormalizeExtension(extension));
        return File.Exists(path) ? path : null;
    }

    private static void RemoveExisting(string dir, string kind)
    {
        foreach (var file in Directory.EnumerateFiles(dir, kind + ".*"))
            File.Delete(file);
    }

    private static string NormalizeExtension(string extension) =>
        extension.StartsWith('.') ? extension : "." + extension;
}
