#pragma once

#include <cstdint>
#include <filesystem>
#include <functional>
#include <optional>
#include <stop_token>
#include <string>
#include <vector>

namespace smartcut::media {

struct DecodedPcmAudio {
  int sample_rate{};
  int channels{};
  std::int64_t first_pts{};
  int time_base_num{};
  int time_base_den{};
  std::vector<std::int16_t> samples;
};

enum class AudioDevicePositionUnit { samples, bytes, milliseconds };

std::optional<std::uint64_t> audio_device_position_us(
    std::uint64_t value, AudioDevicePositionUnit unit, int sample_rate,
    int block_align);

DecodedPcmAudio decode_audio_pcm(const std::filesystem::path& path, std::size_t max_sample_frames = 0);
std::string audio_pcm_report(const std::filesystem::path& path, std::size_t max_sample_frames = 0);
std::string audio_waveform_report(const std::filesystem::path& path, std::uint64_t start_us,
                                  std::uint64_t end_us, std::size_t bucket_count);
std::string play_audio_device(const std::filesystem::path& path, std::uint64_t start_us,
                              std::optional<std::uint64_t> end_us = {},
                              std::stop_token stop = {},
                              const std::function<void(std::uint64_t)>& progress = {},
                              const std::function<bool()>& cancel_requested = {},
                              const std::function<double()>& volume_gain = {});

}  // namespace smartcut::media
