/**
 * @file bridge.h
 * @brief Synor Bridge SDK for C
 *
 * Cross-chain asset transfers with lock-mint and burn-unlock patterns.
 */

#ifndef SYNOR_BRIDGE_H
#define SYNOR_BRIDGE_H

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

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== Error Types ==================== */

typedef enum {
    SYNOR_BRIDGE_OK = 0,
    SYNOR_BRIDGE_ERROR_CLIENT_CLOSED,
    SYNOR_BRIDGE_ERROR_NETWORK,
    SYNOR_BRIDGE_ERROR_HTTP,
    SYNOR_BRIDGE_ERROR_ENCODING,
    SYNOR_BRIDGE_ERROR_DECODING,
    SYNOR_BRIDGE_ERROR_INVALID_RESPONSE,
    SYNOR_BRIDGE_ERROR_MEMORY,
    SYNOR_BRIDGE_ERROR_TIMEOUT,
    SYNOR_BRIDGE_ERROR_CONFIRMATIONS_PENDING,
    SYNOR_BRIDGE_ERROR_UNKNOWN
} synor_bridge_error_t;

/* ==================== Configuration ==================== */

typedef struct {
    const char* api_key;
    const char* endpoint;       /* Default: https://bridge.synor.io/v1 */
    uint32_t timeout_ms;        /* Default: 60000 */
    uint32_t retries;           /* Default: 3 */
    bool debug;
} synor_bridge_config_t;

/* ==================== Enums ==================== */

typedef enum {
    SYNOR_CHAIN_SYNOR,
    SYNOR_CHAIN_ETHEREUM,
    SYNOR_CHAIN_POLYGON,
    SYNOR_CHAIN_ARBITRUM,
    SYNOR_CHAIN_OPTIMISM,
    SYNOR_CHAIN_BSC,
    SYNOR_CHAIN_AVALANCHE,
    SYNOR_CHAIN_SOLANA,
    SYNOR_CHAIN_COSMOS
} synor_chain_id_t;

typedef enum {
    SYNOR_ASSET_NATIVE,
    SYNOR_ASSET_ERC20,
    SYNOR_ASSET_ERC721,
    SYNOR_ASSET_ERC1155
} synor_asset_type_t;

typedef enum {
    SYNOR_TRANSFER_PENDING,
    SYNOR_TRANSFER_LOCKED,
    SYNOR_TRANSFER_CONFIRMING,
    SYNOR_TRANSFER_MINTING,
    SYNOR_TRANSFER_COMPLETED,
    SYNOR_TRANSFER_FAILED,
    SYNOR_TRANSFER_REFUNDED
} synor_transfer_status_t;

typedef enum {
    SYNOR_DIRECTION_LOCK_MINT,
    SYNOR_DIRECTION_BURN_UNLOCK
} synor_transfer_direction_t;

/* ==================== Chain Types ==================== */

typedef struct {
    char* name;
    char* symbol;
    int32_t decimals;
} synor_native_currency_t;

typedef struct {
    synor_chain_id_t id;
    char* name;
    int64_t chain_id;
    char* rpc_url;
    char* explorer_url;
    synor_native_currency_t native_currency;
    int32_t confirmations;
    int32_t estimated_block_time;
    bool supported;
} synor_chain_t;

typedef struct {
    synor_chain_t* chains;
    size_t count;
} synor_chain_list_t;

/* ==================== Asset Types ==================== */

typedef struct {
    char* id;
    char* symbol;
    char* name;
    synor_asset_type_t type;
    synor_chain_id_t chain;
    char* contract_address;
    int32_t decimals;
    char* logo_url;
    bool verified;
} synor_asset_t;

typedef struct {
    synor_asset_t* assets;
    size_t count;
} synor_asset_list_t;

typedef struct {
    synor_asset_t original_asset;
    synor_asset_t wrapped_asset;
    synor_chain_id_t chain;
    char* bridge_contract;
} synor_wrapped_asset_t;

/* ==================== Transfer Types ==================== */

typedef struct {
    char* id;
    synor_transfer_direction_t direction;
    synor_transfer_status_t status;
    synor_chain_id_t source_chain;
    synor_chain_id_t target_chain;
    synor_asset_t asset;
    char* amount;
    char* sender;
    char* recipient;
    char* source_tx_hash;
    char* target_tx_hash;
    char* fee;
    synor_asset_t fee_asset;
    int64_t created_at;
    int64_t updated_at;
    int64_t completed_at;
    char* error_message;
} synor_transfer_t;

typedef struct {
    synor_transfer_t* transfers;
    size_t count;
} synor_transfer_list_t;

typedef struct {
    synor_transfer_status_t* status;  /* NULL for all */
    synor_chain_id_t* source_chain;   /* NULL for all */
    synor_chain_id_t* target_chain;   /* NULL for all */
    int32_t limit;
    int32_t offset;
} synor_transfer_filter_t;

/* ==================== Lock-Mint Types ==================== */

typedef struct {
    char* validator;
    char* signature;
    int64_t timestamp;
} synor_validator_signature_t;

typedef struct {
    char* id;
    char* tx_hash;
    synor_chain_id_t source_chain;
    synor_chain_id_t target_chain;
    synor_asset_t asset;
    char* amount;
    char* sender;
    char* recipient;
    int64_t lock_timestamp;
    int32_t confirmations;
    int32_t required_confirmations;
} synor_lock_receipt_t;

typedef struct {
    synor_lock_receipt_t lock_receipt;
    char** merkle_proof;
    size_t merkle_proof_count;
    char* block_header;
    synor_validator_signature_t* signatures;
    size_t signature_count;
} synor_lock_proof_t;

typedef struct {
    const char* recipient;
    int64_t deadline;
    double slippage;
} synor_lock_options_t;

typedef struct {
    const char* gas_limit;
    const char* max_fee_per_gas;
    const char* max_priority_fee_per_gas;
} synor_mint_options_t;

/* ==================== Burn-Unlock Types ==================== */

typedef struct {
    char* id;
    char* tx_hash;
    synor_chain_id_t source_chain;
    synor_chain_id_t target_chain;
    synor_asset_t wrapped_asset;
    synor_asset_t original_asset;
    char* amount;
    char* sender;
    char* recipient;
    int64_t burn_timestamp;
    int32_t confirmations;
    int32_t required_confirmations;
} synor_burn_receipt_t;

typedef struct {
    synor_burn_receipt_t burn_receipt;
    char** merkle_proof;
    size_t merkle_proof_count;
    char* block_header;
    synor_validator_signature_t* signatures;
    size_t signature_count;
} synor_burn_proof_t;

typedef struct {
    const char* recipient;
    int64_t deadline;
} synor_burn_options_t;

typedef struct {
    const char* gas_limit;
    const char* gas_price;
} synor_unlock_options_t;

/* ==================== Fee Types ==================== */

typedef struct {
    char* bridge_fee;
    char* gas_fee_source;
    char* gas_fee_target;
    char* total_fee;
    synor_asset_t fee_asset;
    int32_t estimated_time;
    char* exchange_rate;
} synor_fee_estimate_t;

typedef struct {
    synor_asset_t from_asset;
    synor_asset_t to_asset;
    char* rate;
    char* inverse_rate;
    int64_t last_updated;
    char* source;
} synor_exchange_rate_t;

/* ==================== Transaction Types ==================== */

typedef struct {
    char* tx_hash;
    synor_chain_id_t chain;
    char* from;
    char* to;
    char* value;
    char* data;
    char* gas_limit;
    char* gas_price;
    char* max_fee_per_gas;
    char* max_priority_fee_per_gas;
    int32_t nonce;
    char* signature;
} synor_signed_tx_t;

/* ==================== Client Handle ==================== */

typedef struct synor_bridge synor_bridge_t;

/* ==================== Lifecycle Functions ==================== */

synor_bridge_t* synor_bridge_create(const synor_bridge_config_t* config);
void synor_bridge_destroy(synor_bridge_t* bridge);
bool synor_bridge_is_closed(synor_bridge_t* bridge);
bool synor_bridge_health_check(synor_bridge_t* bridge);

/* ==================== Chain Operations ==================== */

synor_bridge_error_t synor_bridge_get_supported_chains(synor_bridge_t* bridge,
    synor_chain_list_t* result);
synor_bridge_error_t synor_bridge_get_chain(synor_bridge_t* bridge,
    synor_chain_id_t chain_id, synor_chain_t* result);
bool synor_bridge_is_chain_supported(synor_bridge_t* bridge, synor_chain_id_t chain_id);

void synor_chain_free(synor_chain_t* chain);
void synor_chain_list_free(synor_chain_list_t* list);

/* ==================== Asset Operations ==================== */

synor_bridge_error_t synor_bridge_get_supported_assets(synor_bridge_t* bridge,
    synor_chain_id_t chain_id, synor_asset_list_t* result);
synor_bridge_error_t synor_bridge_get_asset(synor_bridge_t* bridge,
    const char* asset_id, synor_asset_t* result);
synor_bridge_error_t synor_bridge_get_wrapped_asset(synor_bridge_t* bridge,
    const char* original_asset_id, synor_chain_id_t target_chain,
    synor_wrapped_asset_t* result);

void synor_asset_free(synor_asset_t* asset);
void synor_asset_list_free(synor_asset_list_t* list);
void synor_wrapped_asset_free(synor_wrapped_asset_t* asset);

/* ==================== Fee Operations ==================== */

synor_bridge_error_t synor_bridge_estimate_fee(synor_bridge_t* bridge,
    const char* asset, const char* amount,
    synor_chain_id_t source_chain, synor_chain_id_t target_chain,
    synor_fee_estimate_t* result);
synor_bridge_error_t synor_bridge_get_exchange_rate(synor_bridge_t* bridge,
    const char* from_asset, const char* to_asset, synor_exchange_rate_t* result);

void synor_fee_estimate_free(synor_fee_estimate_t* fee);
void synor_exchange_rate_free(synor_exchange_rate_t* rate);

/* ==================== Lock-Mint Flow ==================== */

synor_bridge_error_t synor_bridge_lock(synor_bridge_t* bridge,
    const char* asset, const char* amount, synor_chain_id_t target_chain,
    const synor_lock_options_t* options, synor_lock_receipt_t* result);
synor_bridge_error_t synor_bridge_get_lock_proof(synor_bridge_t* bridge,
    const char* lock_receipt_id, synor_lock_proof_t* result);
synor_bridge_error_t synor_bridge_wait_for_lock_proof(synor_bridge_t* bridge,
    const char* lock_receipt_id, uint32_t poll_interval_ms, uint32_t max_wait_ms,
    synor_lock_proof_t* result);
synor_bridge_error_t synor_bridge_mint(synor_bridge_t* bridge,
    const synor_lock_proof_t* proof, const char* target_address,
    const synor_mint_options_t* options, synor_signed_tx_t* result);

void synor_lock_receipt_free(synor_lock_receipt_t* receipt);
void synor_lock_proof_free(synor_lock_proof_t* proof);

/* ==================== Burn-Unlock Flow ==================== */

synor_bridge_error_t synor_bridge_burn(synor_bridge_t* bridge,
    const char* wrapped_asset, const char* amount,
    const synor_burn_options_t* options, synor_burn_receipt_t* result);
synor_bridge_error_t synor_bridge_get_burn_proof(synor_bridge_t* bridge,
    const char* burn_receipt_id, synor_burn_proof_t* result);
synor_bridge_error_t synor_bridge_wait_for_burn_proof(synor_bridge_t* bridge,
    const char* burn_receipt_id, uint32_t poll_interval_ms, uint32_t max_wait_ms,
    synor_burn_proof_t* result);
synor_bridge_error_t synor_bridge_unlock(synor_bridge_t* bridge,
    const synor_burn_proof_t* proof, const synor_unlock_options_t* options,
    synor_signed_tx_t* result);

void synor_burn_receipt_free(synor_burn_receipt_t* receipt);
void synor_burn_proof_free(synor_burn_proof_t* proof);

/* ==================== Transfer Operations ==================== */

synor_bridge_error_t synor_bridge_get_transfer(synor_bridge_t* bridge,
    const char* transfer_id, synor_transfer_t* result);
synor_bridge_error_t synor_bridge_get_transfer_status(synor_bridge_t* bridge,
    const char* transfer_id, synor_transfer_status_t* status);
synor_bridge_error_t synor_bridge_list_transfers(synor_bridge_t* bridge,
    const synor_transfer_filter_t* filter, synor_transfer_list_t* result);
synor_bridge_error_t synor_bridge_wait_for_transfer(synor_bridge_t* bridge,
    const char* transfer_id, uint32_t poll_interval_ms, uint32_t max_wait_ms,
    synor_transfer_t* result);

void synor_transfer_free(synor_transfer_t* transfer);
void synor_transfer_list_free(synor_transfer_list_t* list);
void synor_signed_tx_free(synor_signed_tx_t* tx);

/* ==================== Convenience Functions ==================== */

synor_bridge_error_t synor_bridge_bridge_to(synor_bridge_t* bridge,
    const char* asset, const char* amount, synor_chain_id_t target_chain,
    const char* target_address, const synor_lock_options_t* lock_options,
    const synor_mint_options_t* mint_options, synor_transfer_t* result);
synor_bridge_error_t synor_bridge_bridge_back(synor_bridge_t* bridge,
    const char* wrapped_asset, const char* amount,
    const synor_burn_options_t* burn_options,
    const synor_unlock_options_t* unlock_options, synor_transfer_t* result);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_BRIDGE_H */
