#pragma once
#include <cstddef>
#include <string>
#include <audioapi/utils/Macros.h>

namespace audioapi::decoding {
/**
 * Incremental PCM decoder: openFile or openMemory → readPcmFrames in a loop → close.
 * Shared contract for FFmpeg-based and MiniAudio-based implementations.
 */
class IIncrementalAudioDecoder {
 public:
  static constexpr size_t CHUNK_SIZE = 4096;
  IIncrementalAudioDecoder() = default;
  virtual ~IIncrementalAudioDecoder() = default;
  DELETE_COPY_AND_MOVE(IIncrementalAudioDecoder);

  /// @brief Opens a file for decoding.
  /// @param outputSampleRate The output sample rate.
  /// @param path The path to the file.
  /// @return True if the file was opened successfully, false otherwise.
  [[nodiscard]] virtual bool openFile(
      int outputSampleRate,
      const std::string &path) = 0;

  /// @brief Opens a memory block for decoding.
  /// @param outputSampleRate The output sample rate.
  /// @param data The data to decode.
  /// @param size The size of the data.
  /// @return True if the memory block was opened successfully, false otherwise.
  [[nodiscard]] virtual bool openMemory(
      int outputSampleRate,
      const void *data,
      size_t size) = 0;

  /// @brief Reads PCM frames from the decoder.
  /// @param outInterleaved The output buffer for the decoded frames.
  /// @param frameCount The number of frames to read.
  /// @return The number of frames read.
  [[nodiscard]] virtual size_t readPcmFrames(float *outInterleaved, size_t frameCount) = 0;

  /// @brief Closes the decoder.
  virtual void close() = 0;

  /// @brief Checks if the decoder is open.
  /// @return True if the decoder is open, false otherwise.
  [[nodiscard]] virtual bool isOpen() const = 0;

  /// @brief Gets the number of output channels.
  /// @return The number of output channels.
  [[nodiscard]] virtual int outputChannels() const = 0;

  /// @brief Gets the output sample rate.
  /// @return The output sample rate.
  [[nodiscard]] virtual int outputSampleRate() const = 0;

  /// @brief Gets the duration of the audio in seconds.
  /// @return The duration of the audio in seconds.
  [[nodiscard]] virtual float getDurationInSeconds() const = 0;

  /// @brief Gets the current position of the audio in seconds.
  /// @return The current position of the audio in seconds.
  [[nodiscard]] virtual float getCurrentPositionInSeconds() const = 0;

  /// @brief Seeks to a specific time in the audio.
  /// @param seconds The time to seek to in seconds.
  /// @return True if the seek was successful, false otherwise.
  [[nodiscard]] virtual bool seekToTime(double seconds) = 0;
};
} // namespace audioapi::decoding
