// plip_virtual — phone-less PLIP annex running on the ESP32-S3-BOX-3.
//
// Implements the PLIP REST contract (PLIP_FIRMWARE/src/network_task.cpp) on
// the box's existing HTTP server:
//   POST /ring   { "duration_ms": 4000 }  → ring cadence on the BOX-3 speaker
//   POST /stop                            → stop ringing
//   POST /play                            → 501 (audio path is the WS TTS)
//   GET  /status                          → { off_hook, ringing, playing }
//
// The BOOT button is the virtual hook switch: a press during the ring picks
// up, a press while off-hook hangs up. Each transition is reported to the
// Zacus master (POST CONFIG_ZACUS_MASTER_URL/voice/hook {state, reason})
// exactly like the real PLIP's zacus_hook_client — the master cannot tell
// the two annexes apart.

#pragma once

#include <stdbool.h>
#include "esp_codec_dev.h"
#include "esp_err.h"
#include "esp_http_server.h"

#ifdef __cplusplus
extern "C" {
#endif

// Hook state, exposed for the on-screen phone UI (plip_ui).
typedef enum {
    PLIP_HOOK_ON = 0,    // idle, handset down
    PLIP_HOOK_RINGING,
    PLIP_HOOK_OFF,       // picked up
} plip_hook_state_t;

// Register the REST handlers on `server` and keep `spk` for the ring tone.
// Call once after scenario_server_start(); the speaker channel must be
// enabled (speaker_init() in main.c).
esp_err_t plip_virtual_init(httpd_handle_t server, esp_codec_dev_handle_t spk);

// Forward a BOOT-button press. Returns true when the press was consumed as
// a hook transition (pickup/hangup) — the caller should then skip its own
// handling (voice-streaming toggle).
bool plip_virtual_button_press(void);

// Programmatic hook transitions (used by the touch UI). Both are no-ops
// when the state does not allow the transition.
void plip_virtual_pickup(void);   // RINGING -> OFF (stops the ring)
void plip_virtual_hangup(void);   // OFF -> ON

// Report a dialed number to the master (reason "dial:<number>" on the
// existing /voice/hook contract) and remember it for GET /status.
// Only meaningful while off-hook; ignored otherwise.
void plip_virtual_dial(const char *number);

// UI notification: called on every hook state change (from HTTP, button or
// touch context — the callback must do its own LVGL locking).
typedef void (*plip_state_cb_t)(plip_hook_state_t state);
void plip_virtual_register_state_cb(plip_state_cb_t cb);

plip_hook_state_t plip_virtual_state(void);

#ifdef __cplusplus
}
#endif
