#ifndef WIFI_COMMAND_POLL_H
#define WIFI_COMMAND_POLL_H

// ============================================================================
// wifi_command_poll.h — inbound tasking over the T1<->C2 direct WiFi bridge
// (c2_wifi_bridge.{h,cpp}).
//
// Closes a real gap: c2_wifi_bridge posts detections/health OUTBOUND but
// never polled C2 for commands, so there was no way for an operator (via
// OpenForge C2 or the PDL Tactical app) to task this sensor without a
// LoRa-connected T2 gateway relaying FOCUS_SENSORS/SET_STEALTH over LoRa --
// which requires hardware that, on this session's build, doesn't exist yet.
// This polls the SAME C2 host/port c2_wifi_bridge_connect() configured,
// using this sensor's own SENSOR_NAME as the gateway_id, so a command
// created with target_gateway_id == SENSOR_NAME reaches this sensor
// directly over WiFi with no T2/LoRa hop at all.
//
// Reuses the T1 command engine that already exists for LoRa-delivered
// commands (command_handler.h's dispatchCommand()) rather than
// reimplementing tasking logic -- this module is purely a WiFi transport
// adapter: JSON in, CmdPacket out, dispatchCommand(), AckPacket back to
// JSON, POST result to C2. Supports the subset of SensorCmdType that is
// genuinely "what to look for" tasking (frequency focus, detection
// threshold, stealth, TX power, on-demand status/scan) -- provisioning/
// maintenance command types (UPDATE_MODEL_SLOT, MQTT_PROVISION, etc.) stay
// LoRa/T2-only for now.
//
// C2 command shapes accepted (top-level `type`, both already valid in
// OpenForge C2's COMMAND_TYPES enum -- no C2-side changes needed):
//   {"type":"FOCUS_SENSORS","params":{"cmd_type":"FOCUS_FREQ","freq_mhz":915.0,
//    "duration_sec":30,"chan_hint":0}}
//   {"type":"FOCUS_SENSORS","params":{"cmd_type":"SET_THRESHOLD","model_id":0,
//    "threshold_pct":80}}
//   {"type":"FOCUS_SENSORS","params":{"cmd_type":"SET_TX_POWER","tx_power_dbm":14}}
//   {"type":"FOCUS_SENSORS","params":{"cmd_type":"REPORT_STATUS"}}
//   {"type":"FOCUS_SENSORS","params":{"cmd_type":"NETWORK_SCAN_DUMP"}}
//   {"type":"SET_STEALTH","params":{"enable":true,"tx_power_dbm":5,"duration_min":10}}
//   {"type":"SET_STEALTH","params":{"enable":false}}
// ============================================================================

#include <cstddef>
#include <cstdint>
#include "command_handler.h"

// ---------------------------------------------------------------------------
// Pure parsing/building functions -- no ARDUINO dependency, directly
// unit-testable on the host (matches mythos_bridge.cpp's split).
// ---------------------------------------------------------------------------

// Extracts the first command's "id" and "type" string fields from a raw
// GET /api/sensor/commands response body. Returns false if the response
// has count==0 or no commands[] entry (nothing to do -- not an error).
bool wcp_extract_command_id_type(
    const char* body,
    char* out_id, size_t id_cap,
    char* out_type, size_t type_cap);

// Resolves the actual SensorCmdType to execute from the top-level `type`
// plus the command's `params` object, and fills a CmdPacket ready for
// dispatchCommand(). target_sensor_id is this sensor's own id (echoed into
// the packet; dispatchCommand doesn't target-check WiFi-delivered commands
// since there's no broadcast concept on this direct path).
// Returns false if `type`/`params.cmd_type` doesn't resolve to one of the
// supported tasking command types -- caller should report a clear
// "unsupported command type" result rather than silently drop it.
bool wcp_build_cmd_packet(
    const char* body, uint16_t own_sensor_id, CmdPacket& out);

// Builds the JSON body for POST /api/sensor/command/:id/result, from the
// AckPacket dispatchCommand() produced plus optional extra status fields
// (only populated for REPORT_STATUS -- 0/empty elsewhere). gateway_id is
// this sensor's own SENSOR_NAME (required field on the result payload).
// started_at/completed_at are unix seconds; execution_time_ms as measured.
// Returns the number of bytes written, or 0 if out_cap was too small.
size_t wcp_build_result_json(
    const AckPacket& ack, bool dispatch_recognized,
    const char* gateway_id,
    uint32_t started_at, uint32_t completed_at, uint32_t execution_time_ms,
    bool have_status_extra, uint8_t battery_pct, int8_t wifi_rssi,
    bool stealth_active, uint32_t uptime_s, uint32_t free_heap_bytes,
    char* out, size_t out_cap);

#ifdef ARDUINO
// ---------------------------------------------------------------------------
// ARDUINO-only poll loop. Shares c2_wifi_bridge's configured host/port
// (call after c2_wifi_bridge_connect()); no separate connect step needed.
// ---------------------------------------------------------------------------

void wifi_command_poll_init(uint16_t own_sensor_id);

// Drives the periodic command poll (WCP_POLL_INTERVAL_MS) -- call every
// loop() cycle alongside c2_wifi_bridge_tick(). No-op until
// c2_wifi_bridge_connect() has configured a host/port and WiFi is up.
void wifi_command_poll_tick();

struct WifiCommandPollStats {
    bool     configured;
    uint32_t polls_ok;
    uint32_t polls_failed;
    uint32_t commands_seen;
    uint32_t commands_executed_ok;
    uint32_t commands_executed_failed;
    uint32_t commands_unsupported;
};

void wifi_command_poll_get_stats(WifiCommandPollStats* out);
#endif

#endif // WIFI_COMMAND_POLL_H
