#ifndef WEBRTCPUSH_WS_SIGNALING_H
#define WEBRTCPUSH_WS_SIGNALING_H

// WebSocket 信令客户端 (匹配 https://jywy.yd-ss.com 协议, 实测 signal.js/client.js)
//   wss://signal.yd-ss.com/websocket?dev=<roomId>
//
// 消息协议 (JSON, MSG_TYPE={id,offer,answer,pong,num,overload,leave}):
//   <- {"type":"id","message":"<memberId>"}              服务端分配本端 ID
//   <- {"type":"num","message":<n>}                       房间在线人数 (数字或字符串)
//   <- {"type":"offer","description":{"type":"offer","sdp":"..."}}   拉流端发来的 offer
//   <- {"type":"answer","description":{...}}              对我方兜底 offer 的回答
//   <- {"memberId":"<对端>","candidate":{...}}             对端 ICE candidate (无 type)
//   <- {"type":"pong",...}                                 心跳回应
//   <- {"type":"leave","message":"<memberId>"}             有人离开
//   <- {"type":"overload",...}                             服务器过载
//   -> {"memberId":"<本端>","description":{"type":"offer|answer","sdp":"..."}}
//   -> {"memberId":"<本端>","candidate":{"candidate":"...","sdpMid":"...","sdpMLineIndex":0}}
//   -> {"type":"ping","message":"keeplive"}                10s 心跳
//
// 保活/重连 (对齐 signal.js): 每 10s ping; 超过 25s 没收到 pong 自动重连;
// 连接被断开 2s 后自动重连。

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

namespace webrtcpush {

struct SignalMessage {
    enum class Type {
        Unknown = 0,
        Id,            // message = memberId 字符串
        Num,           // num = 房间人数
        Offer,         // sdp (拉流端主动发来的 offer, 设备应答)
        Answer,        // sdp (对设备兜底 offer 的回答)
        Candidate,     // candidate_json + sender_id
        Pong,
        Leave,         // sender_id/message = 离开者的 memberId
        Overload,
    };
    Type        type = Type::Unknown;
    std::string sdp;             // Offer / Answer 的完整 SDP
    std::string candidate_json;  // ICE candidate 的原始 JSON 字符串 (对象形式, 已 dump)
    std::string message;         // Id 消息的 memberId 或其他文本
    std::string sender_id;       // 对端 memberId (candidate/leave 消息里带)
    int         num = 0;         // Num 消息的房间人数
};

class WsSignaling {
public:
    using MessageCallback = std::function<void(const SignalMessage&)>;
    using StateCallback   = std::function<void(bool open)>;

    explicit WsSignaling(std::string url);
    ~WsSignaling();

    // 启动连接 + 内置保活线程 (自动 ping/pong/重连)
    bool start();
    void stop();

    void set_message_callback(MessageCallback cb);
    void set_state_callback(StateCallback cb);

    // 本地 memberId (收到 Id 消息后自动保存; 重连后会更新)
    std::string member_id() const;

    // 发送 offer 或 answer
    //   {"memberId":"...","description":{"type":"offer|answer","sdp":"..."}}
    bool send_description(const std::string &sdp, bool is_offer,
                          bool log_result = true);

    // 发送本地 ICE candidate
    //   {"memberId":"...","candidate":{...}}
    bool send_candidate(const std::string &candidate_json,
                        bool log_result = true);

private:
    struct Impl;
    std::unique_ptr<Impl> impl_;
};

} // namespace webrtcpush

#endif // WEBRTCPUSH_WS_SIGNALING_H
