#pragma once

#include <functional>
#include <string>
#include <cstdint>

#ifdef ESP_PLATFORM
#include <esp_gatts_api.h>
#include <esp_gap_ble_api.h>
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#endif

struct cJSON;

class BleJsonService {
public:
    // 收到 JSON 命令时的回调: cmd, msg_id, data(cJSON*)
    using CommandCallback = std::function<void(const std::string& cmd, int msg_id, cJSON* data)>;

    BleJsonService();
    ~BleJsonService();

    // 初始化 GATT 服务 (需在 Bluedroid 栈已启动后调用)
    bool Initialize();

    // 启动广播和服务
    bool Start(const char* device_name = nullptr);

    // 停止服务和广播
    void Stop();

    // 发送 JSON 响应 (通过 NOTIFY)
    bool SendResponse(const std::string& cmd, int msg_id, int code,
                      const char* msg = nullptr, cJSON* data = nullptr);

    // 发送主动事件推送 (通过 NOTIFY)
    bool SendEvent(const std::string& event_type, cJSON* data = nullptr);

    // 注册命令处理回调
    void SetCommandCallback(CommandCallback callback) { command_callback_ = callback; }

    // 状态查询
    bool IsConnected() const { return connected_; }
    bool IsNotifyEnabled() const { return notify_enabled_; }
    uint16_t GetMtu() const { return mtu_; }

private:
    // 禁用拷贝
    BleJsonService(const BleJsonService&) = delete;
    BleJsonService& operator=(const BleJsonService&) = delete;

#ifdef ESP_PLATFORM
    // GATTS 事件回调 (static -> instance)
    static void GattsEventHandler(esp_gatts_cb_event_t event,
                                  esp_gatt_if_t gatts_if,
                                  esp_ble_gatts_cb_param_t* param);

    // GAP 事件回调
    static void GapEventHandler(esp_gap_ble_cb_event_t event,
                                esp_ble_gap_cb_param_t* param);

    // 内部事件处理
    void HandleGattsEvent(esp_gatts_cb_event_t event,
                          esp_gatt_if_t gatts_if,
                          esp_ble_gatts_cb_param_t* param);

    // 创建 Service 和 Characteristic
    void CreateService(esp_gatt_if_t gatts_if);

    // 配置并启动广播
    void StartAdvertising();

    // 处理 WRITE 收到的数据
    void ProcessWriteData(const uint8_t* data, uint16_t len);

    // 通过 NOTIFY 发送数据
    bool SendNotify(const char* json_str, uint16_t len);

    // 命令处理任务 (从队列中取出 JSON 命令并分发)
    static void CmdProcessTask(void* param);

    // GATT handles
    uint16_t service_handle_ = 0;
    uint16_t write_char_handle_ = 0;
    uint16_t notify_char_handle_ = 0;
    uint16_t notify_cccd_handle_ = 0;
    uint16_t status_char_handle_ = 0;

    // 接口信息
    esp_gatt_if_t gatts_if_ = ESP_GATT_IF_NONE;
    uint16_t conn_id_ = 0;

    // 命令处理队列
    QueueHandle_t cmd_queue_ = nullptr;
    TaskHandle_t cmd_task_handle_ = nullptr;
#endif

    // 状态
    bool initialized_ = false;
    bool connected_ = false;
    bool notify_enabled_ = false;
    uint16_t mtu_ = 23;

    // 服务创建阶段计数 (跟踪 add_char 完成数)
    int chars_added_ = 0;

    // 回调
    CommandCallback command_callback_;

    // 设备名
    std::string device_name_;

    // 单例指针供 static 回调使用
    static BleJsonService* instance_;
};
