using System.Globalization;
using System.Text.Json;
using Microsoft.Extensions.Options;
using TeleWave.Application.Common.Interfaces;

namespace TeleWave.Infrastructure.Media;

/// <summary>
/// Замер длительности аудиофайла через ffprobe (format.duration). Используется при загрузке звука
/// блока заставки, чтобы длина заставки шла по длине звука.
/// </summary>
public sealed class FfprobeAudioProbe(IOptions<MediaOptions> mediaOptions) : IAudioProbe
{
    private readonly MediaOptions _media = mediaOptions.Value;

    public async Task<TimeSpan?> TryGetDurationAsync(
        string absolutePath,
        CancellationToken cancellationToken
    )
    {
        if (!File.Exists(absolutePath))
            return null;

        try
        {
            var result = await ProcessRunner.RunAsync(
                _media.FfprobePath,
                ["-v", "quiet", "-print_format", "json", "-show_format", absolutePath],
                lowPriority: false,
                TimeSpan.FromSeconds(_media.ProbeTimeoutSeconds),
                cancellationToken
            );
            if (result.ExitCode != 0)
                return null;

            using var doc = JsonDocument.Parse(result.StdOut);
            if (
                doc.RootElement.TryGetProperty("format", out var format)
                && format.TryGetProperty("duration", out var durEl)
                && double.TryParse(
                    durEl.GetString(),
                    NumberStyles.Float,
                    CultureInfo.InvariantCulture,
                    out var seconds
                )
                && seconds > 0
            )
                return TimeSpan.FromSeconds(seconds);
        }
        catch (Exception ex) when (ex is JsonException or InvalidOperationException)
        {
            // Не удалось разобрать вывод ffprobe — длину не знаем.
        }

        return null;
    }
}
