/**
 * @file dex.h
 * @brief Synor DEX SDK for C
 *
 * Complete decentralized exchange client with support for:
 * - AMM swaps (constant product, stable, concentrated)
 * - Liquidity provision
 * - Perpetual futures (up to 100x leverage)
 * - Order books (limit orders)
 * - Farming & staking
 */

#ifndef SYNOR_DEX_H
#define SYNOR_DEX_H

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

#ifdef __cplusplus
extern "C" {
#endif

/* Error codes */
typedef enum {
    SYNOR_DEX_OK = 0,
    SYNOR_DEX_ERROR_CLIENT_CLOSED = -1,
    SYNOR_DEX_ERROR_HTTP = -2,
    SYNOR_DEX_ERROR_NETWORK = -3,
    SYNOR_DEX_ERROR_INVALID_PARAM = -4,
    SYNOR_DEX_ERROR_TIMEOUT = -5,
    SYNOR_DEX_ERROR_JSON = -6,
    SYNOR_DEX_ERROR_ALLOCATION = -7
} synor_dex_error_t;

/* Enums */
typedef enum {
    SYNOR_DEX_POOL_TYPE_CONSTANT_PRODUCT,
    SYNOR_DEX_POOL_TYPE_STABLE,
    SYNOR_DEX_POOL_TYPE_CONCENTRATED
} synor_dex_pool_type_t;

typedef enum {
    SYNOR_DEX_POSITION_SIDE_LONG,
    SYNOR_DEX_POSITION_SIDE_SHORT
} synor_dex_position_side_t;

typedef enum {
    SYNOR_DEX_ORDER_TYPE_MARKET,
    SYNOR_DEX_ORDER_TYPE_LIMIT,
    SYNOR_DEX_ORDER_TYPE_STOP_MARKET,
    SYNOR_DEX_ORDER_TYPE_STOP_LIMIT,
    SYNOR_DEX_ORDER_TYPE_TAKE_PROFIT,
    SYNOR_DEX_ORDER_TYPE_TAKE_PROFIT_LIMIT
} synor_dex_order_type_t;

typedef enum {
    SYNOR_DEX_MARGIN_TYPE_CROSS,
    SYNOR_DEX_MARGIN_TYPE_ISOLATED
} synor_dex_margin_type_t;

typedef enum {
    SYNOR_DEX_TIME_IN_FORCE_GTC,
    SYNOR_DEX_TIME_IN_FORCE_IOC,
    SYNOR_DEX_TIME_IN_FORCE_FOK,
    SYNOR_DEX_TIME_IN_FORCE_GTD
} synor_dex_time_in_force_t;

typedef enum {
    SYNOR_DEX_ORDER_STATUS_PENDING,
    SYNOR_DEX_ORDER_STATUS_OPEN,
    SYNOR_DEX_ORDER_STATUS_PARTIALLY_FILLED,
    SYNOR_DEX_ORDER_STATUS_FILLED,
    SYNOR_DEX_ORDER_STATUS_CANCELLED,
    SYNOR_DEX_ORDER_STATUS_EXPIRED
} synor_dex_order_status_t;

/* Opaque handle types */
typedef struct synor_dex_client synor_dex_client_t;
typedef struct synor_dex_perps_client synor_dex_perps_client_t;
typedef struct synor_dex_orderbook_client synor_dex_orderbook_client_t;
typedef struct synor_dex_farms_client synor_dex_farms_client_t;

/* Configuration */
typedef struct {
    const char* api_key;
    const char* endpoint;        /* Default: "https://dex.synor.io/v1" */
    const char* ws_endpoint;     /* Default: "wss://dex.synor.io/v1/ws" */
    uint32_t timeout_ms;         /* Default: 30000 */
    uint32_t retries;            /* Default: 3 */
    bool debug;                  /* Default: false */
} synor_dex_config_t;

/* Data types */
typedef struct {
    char* address;
    char* symbol;
    char* name;
    int decimals;
    char* total_supply;
    double* price_usd;           /* NULL if not available */
    char* logo_url;              /* NULL if not available */
    bool verified;
} synor_dex_token_t;

typedef struct {
    char* id;
    synor_dex_token_t token_a;
    synor_dex_token_t token_b;
    synor_dex_pool_type_t pool_type;
    char* reserve_a;
    char* reserve_b;
    double fee;
    double tvl_usd;
    double volume_24h;
    double apr;
    char* lp_token_address;
} synor_dex_pool_t;

typedef struct {
    char* token_in;
    char* token_out;
    char* amount_in;
    char* amount_out;
    double price_impact;
    char** route;
    size_t route_count;
    char* fee;
    char* minimum_received;
    int64_t expires_at;
} synor_dex_quote_t;

typedef struct {
    const char* token_in;
    const char* token_out;
    const char* amount_in;
    double slippage;             /* Default: 0.005 */
} synor_dex_quote_params_t;

typedef struct {
    const char* token_in;
    const char* token_out;
    const char* amount_in;
    const char* min_amount_out;
    int64_t deadline;            /* 0 for default */
    const char* recipient;       /* NULL for self */
} synor_dex_swap_params_t;

typedef struct {
    char* transaction_hash;
    char* amount_in;
    char* amount_out;
    double effective_price;
    char* fee_paid;
    char** route;
    size_t route_count;
} synor_dex_swap_result_t;

typedef struct {
    const char* token_a;
    const char* token_b;
    const char* amount_a;
    const char* amount_b;
    const char* min_amount_a;    /* NULL for no minimum */
    const char* min_amount_b;    /* NULL for no minimum */
    int64_t deadline;            /* 0 for default */
} synor_dex_add_liquidity_params_t;

typedef struct {
    const char* pool;
    const char* lp_amount;
    const char* min_amount_a;    /* NULL for no minimum */
    const char* min_amount_b;    /* NULL for no minimum */
    int64_t deadline;            /* 0 for default */
} synor_dex_remove_liquidity_params_t;

typedef struct {
    char* transaction_hash;
    char* amount_a;
    char* amount_b;
    char* lp_tokens;
    double pool_share;
} synor_dex_liquidity_result_t;

typedef struct {
    char* pool_id;
    char* lp_tokens;
    char* token_a_amount;
    char* token_b_amount;
    double value_usd;
    char* unclaimed_fees_a;
    char* unclaimed_fees_b;
    double impermanent_loss;
} synor_dex_lp_position_t;

typedef struct {
    char* symbol;
    char* base_asset;
    char* quote_asset;
    double index_price;
    double mark_price;
    double funding_rate;
    int64_t next_funding_time;
    char* open_interest;
    double volume_24h;
    int max_leverage;
} synor_dex_perp_market_t;

typedef struct {
    const char* market;
    synor_dex_position_side_t side;
    const char* size;
    int leverage;
    synor_dex_order_type_t order_type;
    double* limit_price;         /* NULL for market orders */
    double* stop_loss;           /* NULL if not set */
    double* take_profit;         /* NULL if not set */
    synor_dex_margin_type_t margin_type;
    bool reduce_only;
} synor_dex_open_position_params_t;

typedef struct {
    const char* market;
    const char* size;            /* NULL for entire position */
    synor_dex_order_type_t order_type;
    double* limit_price;         /* NULL for market orders */
} synor_dex_close_position_params_t;

typedef struct {
    char* id;
    char* market;
    synor_dex_position_side_t side;
    char* size;
    double entry_price;
    double mark_price;
    double liquidation_price;
    char* margin;
    int leverage;
    char* unrealized_pnl;
} synor_dex_perp_position_t;

typedef struct {
    int64_t timestamp;
    double open;
    double high;
    double low;
    double close;
    double volume;
} synor_dex_ohlcv_t;

typedef struct {
    double volume_24h;
    double volume_7d;
    double volume_30d;
    int trades_24h;
} synor_dex_volume_stats_t;

typedef struct {
    double total_tvl;
    double pools_tvl;
    double farms_tvl;
    double perps_tvl;
} synor_dex_tvl_stats_t;

/* Callbacks */
typedef void (*synor_dex_callback_t)(synor_dex_error_t error, void* result, void* user_data);

/* Client lifecycle */
synor_dex_error_t synor_dex_create(synor_dex_client_t** client, const synor_dex_config_t* config);
void synor_dex_destroy(synor_dex_client_t* client);
bool synor_dex_is_closed(const synor_dex_client_t* client);
void synor_dex_close(synor_dex_client_t* client);

/* Token operations */
synor_dex_error_t synor_dex_get_token(synor_dex_client_t* client, const char* address,
                                       synor_dex_token_t** token);
synor_dex_error_t synor_dex_list_tokens(synor_dex_client_t* client,
                                         synor_dex_token_t** tokens, size_t* count);
synor_dex_error_t synor_dex_search_tokens(synor_dex_client_t* client, const char* query,
                                           synor_dex_token_t** tokens, size_t* count);

/* Pool operations */
synor_dex_error_t synor_dex_get_pool(synor_dex_client_t* client,
                                      const char* token_a, const char* token_b,
                                      synor_dex_pool_t** pool);
synor_dex_error_t synor_dex_list_pools(synor_dex_client_t* client,
                                        synor_dex_pool_t** pools, size_t* count);

/* Swap operations */
synor_dex_error_t synor_dex_get_quote(synor_dex_client_t* client,
                                       const synor_dex_quote_params_t* params,
                                       synor_dex_quote_t** quote);
synor_dex_error_t synor_dex_swap(synor_dex_client_t* client,
                                  const synor_dex_swap_params_t* params,
                                  synor_dex_swap_result_t** result);

/* Liquidity operations */
synor_dex_error_t synor_dex_add_liquidity(synor_dex_client_t* client,
                                           const synor_dex_add_liquidity_params_t* params,
                                           synor_dex_liquidity_result_t** result);
synor_dex_error_t synor_dex_remove_liquidity(synor_dex_client_t* client,
                                              const synor_dex_remove_liquidity_params_t* params,
                                              synor_dex_liquidity_result_t** result);
synor_dex_error_t synor_dex_get_my_positions(synor_dex_client_t* client,
                                              synor_dex_lp_position_t** positions, size_t* count);

/* Analytics */
synor_dex_error_t synor_dex_get_price_history(synor_dex_client_t* client,
                                               const char* pair, const char* interval, int limit,
                                               synor_dex_ohlcv_t** candles, size_t* count);
synor_dex_error_t synor_dex_get_volume_stats(synor_dex_client_t* client,
                                              synor_dex_volume_stats_t** stats);
synor_dex_error_t synor_dex_get_tvl(synor_dex_client_t* client, synor_dex_tvl_stats_t** stats);

/* Health check */
synor_dex_error_t synor_dex_health_check(synor_dex_client_t* client, bool* healthy);

/* Sub-clients */
synor_dex_perps_client_t* synor_dex_perps(synor_dex_client_t* client);
synor_dex_orderbook_client_t* synor_dex_orderbook(synor_dex_client_t* client);
synor_dex_farms_client_t* synor_dex_farms(synor_dex_client_t* client);

/* Perps operations */
synor_dex_error_t synor_dex_perps_list_markets(synor_dex_perps_client_t* client,
                                                synor_dex_perp_market_t** markets, size_t* count);
synor_dex_error_t synor_dex_perps_get_market(synor_dex_perps_client_t* client,
                                              const char* symbol,
                                              synor_dex_perp_market_t** market);
synor_dex_error_t synor_dex_perps_open_position(synor_dex_perps_client_t* client,
                                                 const synor_dex_open_position_params_t* params,
                                                 synor_dex_perp_position_t** position);
synor_dex_error_t synor_dex_perps_close_position(synor_dex_perps_client_t* client,
                                                  const synor_dex_close_position_params_t* params,
                                                  synor_dex_perp_position_t** position);
synor_dex_error_t synor_dex_perps_get_positions(synor_dex_perps_client_t* client,
                                                 synor_dex_perp_position_t** positions, size_t* count);

/* Memory management */
void synor_dex_free_token(synor_dex_token_t* token);
void synor_dex_free_tokens(synor_dex_token_t* tokens, size_t count);
void synor_dex_free_pool(synor_dex_pool_t* pool);
void synor_dex_free_pools(synor_dex_pool_t* pools, size_t count);
void synor_dex_free_quote(synor_dex_quote_t* quote);
void synor_dex_free_swap_result(synor_dex_swap_result_t* result);
void synor_dex_free_liquidity_result(synor_dex_liquidity_result_t* result);
void synor_dex_free_lp_positions(synor_dex_lp_position_t* positions, size_t count);
void synor_dex_free_perp_market(synor_dex_perp_market_t* market);
void synor_dex_free_perp_markets(synor_dex_perp_market_t* markets, size_t count);
void synor_dex_free_perp_position(synor_dex_perp_position_t* position);
void synor_dex_free_perp_positions(synor_dex_perp_position_t* positions, size_t count);
void synor_dex_free_ohlcv(synor_dex_ohlcv_t* candles, size_t count);
void synor_dex_free_volume_stats(synor_dex_volume_stats_t* stats);
void synor_dex_free_tvl_stats(synor_dex_tvl_stats_t* stats);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_DEX_H */
