#ifndef OTA_OFFER_PROTOCOL_H
#define OTA_OFFER_PROTOCOL_H

#include <stdbool.h>
#include <stdint.h>

#include "cJSON.h"

/** 设备 → 手机：询问是否 OTA（手机 message_type=6 后回复）及 OTA 结束汇报 */
#define OTA_MSG_DEVICE_OFFER     1002
/** 手机 → 设备：同意开始二进制 OTA（随后发 0x01/0x02/0x03） */
#define OTA_MSG_PHONE_OTA_START  0

/** OTA 结束 1002/done 重复发送次数（提高手机收包成功率后再重启切分区） */
#define OTA_DONE_REPORT_COUNT    3
/** 各次 done JSON 之间的间隔（ms） */
#define OTA_DONE_REPORT_GAP_MS   100
/** 发完 done 重复包后、重启前的额外等待（ms，留给 UART DMA 发完） */
#define OTA_DONE_REBOOT_DELAY_MS 400

typedef void (*ota_offer_done_cb_t)(bool success, uint32_t bytes_written, const char *err_step);

/** 上电/链路启动时调用，允许再次发送询问 JSON */
void ota_offer_reset_boot(void);

/** @deprecated 已由 message_type=6 触发；保留供兼容 */
bool ota_offer_mark_query_sent(void);

/** @deprecated */
void ota_offer_reset_query_sent(void);

/** OTA 二进制结束/失败时由 ota_binary_stream 调用 */
void ota_offer_notify_done(bool success, uint32_t bytes_written, const char *err_step);

/** 是否已允许接收 OTA 二进制（手机已回复 message_type=0） */
bool ota_offer_is_armed(void);

/** 取消 OTA 武装（链路清空/卡顿恢复时调用，不重置开机询问标记） */
void ota_offer_disarm(void);

/**
 * 解析手机 JSON；head.message_type==0 时置位 armed 并返回 true
 */
bool ota_offer_parse_phone_response(cJSON *root);

/** 构造询问 JSON：head.message_type=1002, body.phase=query */
char *ota_offer_query_json_malloc(const char *device_id);

/** 构造 OTA 进行中 JSON：head.message_type=1002, body.phase=active（替代心跳） */
char *ota_offer_active_json_malloc(const char *device_id);

/** 构造结果 JSON：head.message_type=1002, body.phase=done */
char *ota_offer_result_json_malloc(const char *device_id,
                                   bool success,
                                   uint32_t bytes_written,
                                   const char *err_step);

/** OTA 是否进行中（已武装或正在写 Flash） */
bool ota_offer_session_busy(void);

/**
 * 链路异常中止：若 OTA 进行中则上报 1002/done(ok=0) 并解除武装。
 * @param err_step 错误码，如 timeout / reset / disconnect
 */
void ota_offer_report_abort(const char *err_step);

void ota_offer_set_done_callback(ota_offer_done_cb_t cb);

#endif
