#pragma once

#include <stdint.h>

#include "driver/i2c_master.h"
#include "esp_err.h"
#include "voice_capture_limits.h"

enum class audio_notification_t : uint8_t {
    DONE = 0,
    FAILED = 1,
    APPROVAL = 2,
};

esp_err_t audio_backend_init(i2c_master_bus_handle_t i2c_bus);
bool audio_backend_notify(audio_notification_t kind);
bool audio_backend_ready(void);
esp_err_t audio_backend_set_volume(uint8_t percent);

// Control-only capture signalling. PCM is retained in an owned PSRAM buffer by
// the microphone task so a stalled upload never truncates a recording.
static constexpr size_t AUDIO_CAPTURE_BYTES = 3528;
enum class CaptureKind : uint8_t { START, PCM, END, CANCEL };
struct AudioCaptureFrame {
    uint64_t id;
    CaptureKind kind;
    size_t size;  // recorded bytes at END/CANCEL; progress marker otherwise
};
bool audio_backend_record_start(uint64_t id);
uint64_t audio_backend_record_started_ms(uint64_t id);
// True length of a finished capture, frozen when capture stopped. Independent
// of the upload, so a slow weak-network transfer cannot inflate the duration.
uint64_t audio_backend_record_duration_ms(uint64_t id);
void audio_backend_record_stop(bool cancel);
bool audio_backend_take_capture(AudioCaptureFrame *frame);
// Owned read-only view of the finished recording, valid until the next
// audio_backend_record_start. Returns nullptr when nothing was captured.
const uint8_t *audio_backend_capture_pcm(size_t *bytes);
void audio_backend_capture_release(uint64_t id);
size_t audio_backend_capture_capacity();

static constexpr size_t AUDIO_SPEECH_BYTES = 7056;
static constexpr unsigned AUDIO_SPEECH_QUEUE_FRAMES = 128;
bool audio_backend_speech_start(uint32_t id, size_t pcm_bytes = 0, const char *sha256 = "");
bool audio_backend_speech_push(uint32_t id, const uint8_t *pcm, size_t size, bool end = false);
void audio_backend_speech_stop();
bool audio_backend_speech_active(uint32_t id);
unsigned audio_backend_speech_played(uint32_t id);
bool audio_backend_speech_buffering(uint32_t id);
