/**
 * Synor Contract SDK for C
 * Smart contract deployment, interaction, and event handling.
 */

#ifndef SYNOR_CONTRACT_H
#define SYNOR_CONTRACT_H

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

#ifdef __cplusplus
extern "C" {
#endif

#define SYNOR_CONTRACT_VERSION "0.1.0"

/* ==================== Error Handling ==================== */

typedef enum {
    SYNOR_CONTRACT_OK = 0,
    SYNOR_CONTRACT_ERR_NULL_PARAM = -1,
    SYNOR_CONTRACT_ERR_HTTP = -2,
    SYNOR_CONTRACT_ERR_JSON = -3,
    SYNOR_CONTRACT_ERR_API = -4,
    SYNOR_CONTRACT_ERR_CLOSED = -5,
    SYNOR_CONTRACT_ERR_MEMORY = -6,
    SYNOR_CONTRACT_ERR_TIMEOUT = -7
} SynorContractError;

typedef struct {
    int status_code;
    char *code;
    char *message;
} SynorContractErrorInfo;

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

typedef struct {
    const char *api_key;
    const char *endpoint;
    int timeout_ms;
    int retries;
} SynorContractConfig;

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

typedef struct SynorContractClient SynorContractClient;

/* ==================== ABI Types ==================== */

typedef struct SynorAbiParameter {
    char *name;
    char *type;
    bool indexed;
    struct SynorAbiParameter *components;
    size_t component_count;
} SynorAbiParameter;

typedef struct {
    char *type;
    char *name;
    SynorAbiParameter *inputs;
    size_t input_count;
    SynorAbiParameter *outputs;
    size_t output_count;
    char *state_mutability;
    bool anonymous;
} SynorAbiEntry;

/* ==================== Deployment ==================== */

typedef struct {
    const char *bytecode;
    const SynorAbiEntry *abi;
    size_t abi_count;
    const char **constructor_args;
    size_t constructor_arg_count;
    const char *value;
    int64_t gas_limit;
    const char *gas_price;
    int64_t nonce;
} SynorDeployContractOptions;

typedef struct {
    char *contract_address;
    char *transaction_hash;
    char *deployer;
    int64_t gas_used;
    int64_t block_number;
    char *block_hash;
} SynorDeploymentResult;

/* ==================== Contract Interaction ==================== */

typedef struct {
    const char *contract;
    const char *method;
    const char **args;
    size_t arg_count;
    const SynorAbiEntry *abi;
    size_t abi_count;
} SynorCallContractOptions;

typedef struct {
    const char *contract;
    const char *method;
    const char **args;
    size_t arg_count;
    const SynorAbiEntry *abi;
    size_t abi_count;
    const char *value;
    int64_t gas_limit;
    const char *gas_price;
    int64_t nonce;
} SynorSendContractOptions;

typedef struct SynorEventLog {
    char *address;
    char **topics;
    size_t topic_count;
    char *data;
    int64_t block_number;
    char *transaction_hash;
    int log_index;
    char *block_hash;
    bool removed;
} SynorEventLog;

typedef struct {
    char *transaction_hash;
    int64_t block_number;
    char *block_hash;
    int64_t gas_used;
    char *effective_gas_price;
    char *status;
    SynorEventLog *logs;
    size_t log_count;
} SynorTransactionResult;

/* ==================== Events ==================== */

typedef struct {
    char *name;
    char *signature;
    char *args_json;  /* JSON string for decoded args */
    SynorEventLog log;
} SynorDecodedEvent;

typedef struct {
    const char *contract;
    const char *event;
    int64_t from_block;
    int64_t to_block;
    const char **topics;
    size_t topic_count;
    const SynorAbiEntry *abi;
    size_t abi_count;
} SynorEventFilter;

/* ==================== Gas Estimation ==================== */

typedef struct {
    int64_t gas_limit;
    char *gas_price;
    char *max_fee_per_gas;
    char *max_priority_fee_per_gas;
    char *estimated_cost;
} SynorGasEstimation;

/* ==================== Contract Information ==================== */

typedef struct {
    char *bytecode;
    char *deployed_bytecode;
    int size;
    bool is_contract;
} SynorBytecodeInfo;

typedef struct {
    const char *address;
    const char *source_code;
    const char *compiler_version;
    const char *constructor_args;
    bool optimization;
    int optimization_runs;
    const char *license;
} SynorVerifyContractOptions;

typedef struct {
    bool verified;
    char *address;
    char *compiler_version;
    bool optimization;
    int optimization_runs;
    char *license;
    SynorAbiEntry *abi;
    size_t abi_count;
    char *source_code;
} SynorVerificationResult;

/* ==================== Multicall ==================== */

typedef struct {
    const char *contract;
    const char *method;
    const char **args;
    size_t arg_count;
    const SynorAbiEntry *abi;
    size_t abi_count;
} SynorMulticallRequest;

typedef struct {
    bool success;
    char *result_json;
    char *error;
} SynorMulticallResult;

/* ==================== Client Lifecycle ==================== */

SynorContractError synor_contract_client_create(
    const SynorContractConfig *config,
    SynorContractClient **client
);

void synor_contract_client_close(SynorContractClient *client);

bool synor_contract_client_is_closed(const SynorContractClient *client);

bool synor_contract_health_check(SynorContractClient *client);

const SynorContractErrorInfo* synor_contract_get_last_error(const SynorContractClient *client);

/* ==================== Contract Deployment ==================== */

SynorContractError synor_contract_deploy(
    SynorContractClient *client,
    const SynorDeployContractOptions *options,
    SynorDeploymentResult *result
);

SynorContractError synor_contract_deploy_create2(
    SynorContractClient *client,
    const SynorDeployContractOptions *options,
    const char *salt,
    SynorDeploymentResult *result
);

SynorContractError synor_contract_predict_address(
    SynorContractClient *client,
    const char *bytecode,
    const char *salt,
    const char *deployer,
    char **address
);

/* ==================== Contract Interaction ==================== */

SynorContractError synor_contract_call(
    SynorContractClient *client,
    const SynorCallContractOptions *options,
    char **result_json
);

SynorContractError synor_contract_send(
    SynorContractClient *client,
    const SynorSendContractOptions *options,
    SynorTransactionResult *result
);

/* ==================== Events ==================== */

SynorContractError synor_contract_get_events(
    SynorContractClient *client,
    const SynorEventFilter *filter,
    SynorDecodedEvent **events,
    size_t *event_count
);

SynorContractError synor_contract_get_logs(
    SynorContractClient *client,
    const char *contract,
    int64_t from_block,
    int64_t to_block,
    SynorEventLog **logs,
    size_t *log_count
);

/* ==================== ABI Utilities ==================== */

SynorContractError synor_contract_encode_call(
    SynorContractClient *client,
    const char *method,
    const char **args,
    size_t arg_count,
    const SynorAbiEntry *abi,
    size_t abi_count,
    char **data
);

SynorContractError synor_contract_decode_result(
    SynorContractClient *client,
    const char *data,
    const char *method,
    const SynorAbiEntry *abi,
    size_t abi_count,
    char **result_json
);

SynorContractError synor_contract_get_selector(
    SynorContractClient *client,
    const char *signature,
    char **selector
);

/* ==================== Gas Estimation ==================== */

SynorContractError synor_contract_estimate_gas(
    SynorContractClient *client,
    const SynorCallContractOptions *options,
    const char *value,
    SynorGasEstimation *result
);

/* ==================== Contract Information ==================== */

SynorContractError synor_contract_get_bytecode(
    SynorContractClient *client,
    const char *address,
    SynorBytecodeInfo *result
);

SynorContractError synor_contract_verify(
    SynorContractClient *client,
    const SynorVerifyContractOptions *options,
    SynorVerificationResult *result
);

SynorContractError synor_contract_get_verification_status(
    SynorContractClient *client,
    const char *address,
    SynorVerificationResult *result
);

/* ==================== Multicall ==================== */

SynorContractError synor_contract_multicall(
    SynorContractClient *client,
    const SynorMulticallRequest *requests,
    size_t request_count,
    SynorMulticallResult **results,
    size_t *result_count
);

/* ==================== Storage ==================== */

SynorContractError synor_contract_read_storage(
    SynorContractClient *client,
    const char *contract,
    const char *slot,
    int64_t block_number,
    char **value
);

/* ==================== Memory Management ==================== */

void synor_contract_free_string(char *str);
void synor_contract_free_deployment_result(SynorDeploymentResult *result);
void synor_contract_free_transaction_result(SynorTransactionResult *result);
void synor_contract_free_event_logs(SynorEventLog *logs, size_t count);
void synor_contract_free_decoded_events(SynorDecodedEvent *events, size_t count);
void synor_contract_free_gas_estimation(SynorGasEstimation *estimation);
void synor_contract_free_bytecode_info(SynorBytecodeInfo *info);
void synor_contract_free_verification_result(SynorVerificationResult *result);
void synor_contract_free_multicall_results(SynorMulticallResult *results, size_t count);
void synor_contract_free_abi(SynorAbiEntry *abi, size_t count);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_CONTRACT_H */
