/**
 * @file rpc.h
 * @brief Synor RPC SDK for C
 *
 * Provides blockchain queries, transaction submission, and real-time
 * subscriptions for the Synor blockchain.
 */

#ifndef SYNOR_RPC_H
#define SYNOR_RPC_H

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "wallet.h"  /* For synor_error_t, synor_network_t, synor_priority_t */

#ifdef __cplusplus
extern "C" {
#endif

/* Transaction status */
typedef enum {
    SYNOR_TX_STATUS_PENDING = 0,
    SYNOR_TX_STATUS_CONFIRMED,
    SYNOR_TX_STATUS_FAILED
} synor_tx_status_t;

/* RPC configuration */
typedef struct {
    const char* api_key;
    const char* endpoint;       /* Default: "https://rpc.synor.io/v1" */
    const char* ws_endpoint;    /* Default: "wss://rpc.synor.io/v1/ws" */
    synor_network_t network;    /* Default: SYNOR_NETWORK_MAINNET */
    uint32_t timeout_ms;        /* Default: 30000 */
    uint32_t retries;           /* Default: 3 */
    bool debug;                 /* Default: false */
} synor_rpc_config_t;

/* Opaque RPC client handle */
typedef struct synor_rpc synor_rpc_t;

/* Block header */
typedef struct {
    char* hash;
    int64_t height;
    char* previous_hash;
    int64_t timestamp;
    int32_t version;
    char* merkle_root;
    int64_t nonce;
    double difficulty;
} synor_block_header_t;

/* Script pubkey */
typedef struct {
    char* asm_str;
    char* hex;
    char* type;
    char* address;  /* May be NULL */
} synor_script_pubkey_t;

/* Transaction input */
typedef struct {
    char* txid;
    int32_t vout;
    char* script_sig;  /* May be NULL */
    int64_t sequence;
    char** witness;
    size_t witness_count;
} synor_rpc_tx_input_t;

/* Transaction output */
typedef struct {
    int64_t value;
    int32_t n;
    synor_script_pubkey_t script_pubkey;
} synor_rpc_tx_output_t;

/* Transaction */
typedef struct {
    char* txid;
    char* hash;
    int32_t version;
    int32_t size;
    int32_t weight;
    int64_t lock_time;
    synor_rpc_tx_input_t* inputs;
    size_t input_count;
    synor_rpc_tx_output_t* outputs;
    size_t output_count;
    int64_t fee;
    int32_t confirmations;
    char* block_hash;     /* May be NULL */
    int64_t block_height; /* -1 if not in block */
    int64_t timestamp;    /* -1 if unknown */
    synor_tx_status_t status;
} synor_rpc_transaction_t;

/* Block */
typedef struct {
    char* hash;
    int64_t height;
    char* previous_hash;
    int64_t timestamp;
    int32_t version;
    char* merkle_root;
    int64_t nonce;
    double difficulty;
    synor_rpc_transaction_t* transactions;
    size_t transaction_count;
    int32_t size;
    int32_t weight;
} synor_block_t;

/* Chain info */
typedef struct {
    char* chain;
    int64_t blocks;
    int64_t headers;
    char* best_block_hash;
    double difficulty;
    int64_t median_time;
    double verification_progress;
    char* chain_work;
    bool pruned;
} synor_chain_info_t;

/* Mempool info */
typedef struct {
    int32_t size;
    int64_t bytes;
    int64_t usage;
    int64_t max_mempool;
    double mempool_min_fee;
    double min_relay_tx_fee;
} synor_mempool_info_t;

/* Fee estimate */
typedef struct {
    synor_priority_t priority;
    int64_t fee_rate;
    int32_t estimated_blocks;
} synor_fee_estimate_t;

/* Submit result */
typedef struct {
    char* txid;
    bool accepted;
    char* reason;  /* May be NULL */
} synor_submit_result_t;

/* Subscription handle */
typedef struct synor_subscription synor_subscription_t;

/* Subscription callbacks */
typedef void (*synor_block_callback_t)(const synor_block_t* block, void* user_data);
typedef void (*synor_tx_callback_t)(const synor_rpc_transaction_t* tx, void* user_data);

/**
 * Create a new RPC client.
 */
synor_rpc_t* synor_rpc_create(const synor_rpc_config_t* config);

/**
 * Destroy RPC client and free resources.
 */
void synor_rpc_destroy(synor_rpc_t* rpc);

/* Block operations */

synor_error_t synor_rpc_get_latest_block(
    synor_rpc_t* rpc,
    synor_block_t* result
);

synor_error_t synor_rpc_get_block(
    synor_rpc_t* rpc,
    const char* hash_or_height,
    synor_block_t* result
);

synor_error_t synor_rpc_get_block_header(
    synor_rpc_t* rpc,
    const char* hash_or_height,
    synor_block_header_t* result
);

/* Transaction operations */

synor_error_t synor_rpc_get_transaction(
    synor_rpc_t* rpc,
    const char* txid,
    synor_rpc_transaction_t* result
);

synor_error_t synor_rpc_get_raw_transaction(
    synor_rpc_t* rpc,
    const char* txid,
    char** hex
);

synor_error_t synor_rpc_send_raw_transaction(
    synor_rpc_t* rpc,
    const char* hex,
    synor_submit_result_t* result
);

synor_error_t synor_rpc_decode_raw_transaction(
    synor_rpc_t* rpc,
    const char* hex,
    synor_rpc_transaction_t* result
);

/* Fee estimation */

synor_error_t synor_rpc_estimate_fee(
    synor_rpc_t* rpc,
    synor_priority_t priority,
    synor_fee_estimate_t* result
);

/* Chain information */

synor_error_t synor_rpc_get_chain_info(
    synor_rpc_t* rpc,
    synor_chain_info_t* result
);

synor_error_t synor_rpc_get_mempool_info(
    synor_rpc_t* rpc,
    synor_mempool_info_t* result
);

/* Subscriptions */

synor_subscription_t* synor_rpc_subscribe_blocks(
    synor_rpc_t* rpc,
    synor_block_callback_t callback,
    void* user_data
);

synor_subscription_t* synor_rpc_subscribe_address(
    synor_rpc_t* rpc,
    const char* address,
    synor_tx_callback_t callback,
    void* user_data
);

synor_subscription_t* synor_rpc_subscribe_mempool(
    synor_rpc_t* rpc,
    synor_tx_callback_t callback,
    void* user_data
);

void synor_subscription_cancel(synor_subscription_t* sub);

/* Free functions */
void synor_block_header_free(synor_block_header_t* header);
void synor_block_free(synor_block_t* block);
void synor_rpc_transaction_free(synor_rpc_transaction_t* tx);
void synor_chain_info_free(synor_chain_info_t* info);
void synor_mempool_info_free(synor_mempool_info_t* info);
void synor_submit_result_free(synor_submit_result_t* result);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_RPC_H */
