#ifndef NOSTR_WEBSOCKET_TLS_H
#define NOSTR_WEBSOCKET_TLS_H

#include <stddef.h>
#include <stdint.h>
#include "../cjson/cJSON.h"

#ifdef __cplusplus
extern "C" {
#endif

// WebSocket client state
typedef struct nostr_ws_client nostr_ws_client_t;

// Connection states
typedef enum {
    NOSTR_WS_CONNECTING = 0,
    NOSTR_WS_CONNECTED = 1,
    NOSTR_WS_CLOSING = 2,
    NOSTR_WS_CLOSED = 3,
    NOSTR_WS_ERROR = -1
} nostr_ws_state_t;

// WebSocket opcodes (RFC 6455)
typedef enum {
    WS_OPCODE_CONTINUATION = 0x0,
    WS_OPCODE_TEXT = 0x1,
    WS_OPCODE_BINARY = 0x2,
    WS_OPCODE_CLOSE = 0x8,
    WS_OPCODE_PING = 0x9,
    WS_OPCODE_PONG = 0xA
} ws_opcode_t;

// Error codes
#define NOSTR_WS_SUCCESS        0
#define NOSTR_WS_ERROR_INVALID  -1
#define NOSTR_WS_ERROR_NETWORK  -2
#define NOSTR_WS_ERROR_PROTOCOL -3
#define NOSTR_WS_ERROR_MEMORY   -4
#define NOSTR_WS_ERROR_TLS      -5

// Debug control - uncomment to enable debug output
// #define NOSTR_WS_DEBUG_ENABLED

// ============================================================================
// Core WebSocket Functions (with TLS support)
// ============================================================================

/**
 * Connect to a WebSocket server (supports both ws:// and wss://)
 * @param url WebSocket URL (e.g., "ws://127.0.0.1:7777" or "wss://relay.damus.io")
 * @return WebSocket client handle or NULL on error
 */
nostr_ws_client_t* nostr_ws_connect(const char* url);

/**
 * Close WebSocket connection
 * @param client WebSocket client handle
 * @return 0 on success, negative on error
 */
int nostr_ws_close(nostr_ws_client_t* client);

/**
 * Get current connection state
 * @param client WebSocket client handle
 * @return Connection state
 */
nostr_ws_state_t nostr_ws_get_state(nostr_ws_client_t* client);

/**
 * Send text message to WebSocket server
 * @param client WebSocket client handle
 * @param message Text message to send
 * @return 0 on success, negative on error
 */
int nostr_ws_send_text(nostr_ws_client_t* client, const char* message);

/**
 * Receive message from WebSocket server (blocking)
 * @param client WebSocket client handle
 * @param buffer Buffer to store received message
 * @param buffer_size Size of buffer
 * @param timeout_ms Timeout in milliseconds (0 = no timeout)
 * @return Number of bytes received, negative on error
 */
int nostr_ws_receive(nostr_ws_client_t* client, char* buffer, size_t buffer_size, int timeout_ms);

/**
 * Send ping frame to server
 * @param client WebSocket client handle
 * @return 0 on success, negative on error
 */
int nostr_ws_ping(nostr_ws_client_t* client);

// ============================================================================
// NOSTR-Specific Helper Functions
// ============================================================================

/**
 * Send NOSTR REQ message to relay
 * @param client WebSocket client handle
 * @param subscription_id Subscription ID
 * @param filters JSON array of filters
 * @return 0 on success, negative on error
 */
int nostr_relay_send_req(nostr_ws_client_t* client, const char* subscription_id, cJSON* filters);

/**
 * Send NOSTR EVENT message to relay
 * @param client WebSocket client handle
 * @param event NOSTR event JSON object
 * @return 0 on success, negative on error
 */
int nostr_relay_send_event(nostr_ws_client_t* client, cJSON* event);

/**
 * Send NOSTR CLOSE message to relay
 * @param client WebSocket client handle
 * @param subscription_id Subscription ID to close
 * @return 0 on success, negative on error
 */
int nostr_relay_send_close(nostr_ws_client_t* client, const char* subscription_id);

/**
 * Parse received NOSTR message
 * @param message Raw message string
 * @param message_type Output: message type ("EVENT", "EOSE", "OK", "NOTICE")
 * @param parsed_json Output: parsed JSON object (caller must free)
 * @return 0 on success, negative on error
 */
int nostr_parse_relay_message(const char* message, char** message_type, cJSON** parsed_json);

// ============================================================================
// Utility Functions
// ============================================================================

/**
 * Get error string for error code
 * @param error_code Error code from WebSocket functions
 * @return Human-readable error string
 */
const char* nostr_ws_strerror(int error_code);

/**
 * Set receive timeout for blocking operations
 * @param client WebSocket client handle
 * @param timeout_ms Timeout in milliseconds
 * @return 0 on success, negative on error
 */
int nostr_ws_set_timeout(nostr_ws_client_t* client, int timeout_ms);

#ifdef __cplusplus
}
#endif

#endif // NOSTR_WEBSOCKET_TLS_H
