/**
 * @file mining.h
 * @brief Synor Mining SDK for C
 *
 * Pool connections, block templates, hashrate stats, and GPU management.
 */

#ifndef SYNOR_MINING_H
#define SYNOR_MINING_H

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

#ifdef __cplusplus
extern "C" {
#endif

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

typedef enum {
    SYNOR_MINING_OK = 0,
    SYNOR_MINING_ERROR_CLIENT_CLOSED,
    SYNOR_MINING_ERROR_NETWORK,
    SYNOR_MINING_ERROR_HTTP,
    SYNOR_MINING_ERROR_ENCODING,
    SYNOR_MINING_ERROR_DECODING,
    SYNOR_MINING_ERROR_INVALID_RESPONSE,
    SYNOR_MINING_ERROR_MEMORY,
    SYNOR_MINING_ERROR_TIMEOUT,
    SYNOR_MINING_ERROR_NOT_CONNECTED,
    SYNOR_MINING_ERROR_UNKNOWN
} synor_mining_error_t;

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

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

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

typedef enum {
    SYNOR_DEVICE_CPU,
    SYNOR_DEVICE_GPU_NVIDIA,
    SYNOR_DEVICE_GPU_AMD,
    SYNOR_DEVICE_ASIC
} synor_device_type_t;

typedef enum {
    SYNOR_DEVICE_IDLE,
    SYNOR_DEVICE_MINING,
    SYNOR_DEVICE_ERROR,
    SYNOR_DEVICE_OFFLINE
} synor_device_status_t;

typedef enum {
    SYNOR_CONN_DISCONNECTED,
    SYNOR_CONN_CONNECTING,
    SYNOR_CONN_CONNECTED,
    SYNOR_CONN_RECONNECTING
} synor_connection_status_t;

typedef enum {
    SYNOR_PERIOD_HOUR,
    SYNOR_PERIOD_DAY,
    SYNOR_PERIOD_WEEK,
    SYNOR_PERIOD_MONTH,
    SYNOR_PERIOD_ALL
} synor_time_period_t;

typedef enum {
    SYNOR_SUBMIT_ACCEPTED,
    SYNOR_SUBMIT_REJECTED,
    SYNOR_SUBMIT_STALE
} synor_submit_status_t;

/* ==================== Pool Types ==================== */

typedef struct {
    const char* url;
    const char* user;
    const char* password;
    const char* algorithm;
    double difficulty;
} synor_pool_config_t;

typedef struct {
    char* id;
    char* pool;
    synor_connection_status_t status;
    char* algorithm;
    double difficulty;
    int64_t connected_at;
    int32_t accepted_shares;
    int32_t rejected_shares;
    int32_t stale_shares;
    int64_t last_share_at;
} synor_stratum_connection_t;

typedef struct {
    char* url;
    int32_t workers;
    double hashrate;
    double difficulty;
    int64_t last_block;
    int32_t blocks_found_24h;
    double luck;
} synor_pool_stats_t;

/* ==================== Block Template Types ==================== */

typedef struct {
    char* txid;
    char* data;
    char* fee;
    int32_t weight;
} synor_template_transaction_t;

typedef struct {
    char* id;
    char* previous_block_hash;
    char* merkle_root;
    int64_t timestamp;
    char* bits;
    int64_t height;
    char* coinbase_value;
    synor_template_transaction_t* transactions;
    size_t transactions_count;
    char* target;
    char* algorithm;
    char* extra_nonce;
} synor_block_template_t;

typedef struct {
    char* template_id;
    char* nonce;
    char* extra_nonce;
    int64_t timestamp;
    char* hash;
} synor_mined_work_t;

typedef struct {
    char* hash;
    double difficulty;
    int64_t timestamp;
    bool accepted;
} synor_share_info_t;

typedef struct {
    synor_submit_status_t status;
    synor_share_info_t share;
    bool block_found;
    char* reason;
    char* block_hash;
    char* reward;
} synor_submit_result_t;

/* ==================== Stats Types ==================== */

typedef struct {
    double current;
    double average_1h;
    double average_24h;
    double peak;
    char* unit;
} synor_hashrate_t;

typedef struct {
    int32_t accepted;
    int32_t rejected;
    int32_t stale;
    int32_t total;
    double accept_rate;
} synor_share_stats_t;

typedef struct {
    double current;
    double max;
    bool throttling;
} synor_device_temperature_t;

typedef struct {
    char* today;
    char* yesterday;
    char* this_week;
    char* this_month;
    char* total;
    char* currency;
} synor_earnings_snapshot_t;

typedef struct {
    synor_hashrate_t hashrate;
    synor_share_stats_t shares;
    int64_t uptime;
    double efficiency;
    synor_earnings_snapshot_t earnings;
    double power_consumption;
    synor_device_temperature_t temperature;
} synor_mining_stats_t;

typedef struct {
    int64_t date;
    char* amount;
    int32_t blocks;
    int32_t shares;
    double hashrate;
} synor_earnings_breakdown_t;

typedef struct {
    synor_time_period_t period;
    int64_t start_date;
    int64_t end_date;
    char* amount;
    int32_t blocks;
    int32_t shares;
    double average_hashrate;
    char* currency;
    synor_earnings_breakdown_t* breakdown;
    size_t breakdown_count;
} synor_earnings_t;

/* ==================== Device Types ==================== */

typedef struct {
    char* id;
    char* name;
    synor_device_type_t type;
    synor_device_status_t status;
    double hashrate;
    double temperature;
    double fan_speed;
    double power_draw;
    int64_t memory_used;
    int64_t memory_total;
    char* driver;
    char* firmware;
} synor_mining_device_t;

typedef struct {
    synor_mining_device_t* devices;
    size_t count;
} synor_mining_device_list_t;

typedef struct {
    bool enabled;
    int32_t intensity;
    int32_t power_limit;
    int32_t core_clock_offset;
    int32_t memory_clock_offset;
    int32_t fan_speed;
} synor_device_config_t;

/* ==================== Worker Types ==================== */

typedef struct {
    char* id;
    char* name;
    synor_connection_status_t status;
    synor_hashrate_t hashrate;
    synor_share_stats_t shares;
    synor_mining_device_t* devices;
    size_t devices_count;
    int64_t last_seen;
    int64_t uptime;
} synor_worker_info_t;

typedef struct {
    synor_worker_info_t* workers;
    size_t count;
} synor_worker_info_list_t;

/* ==================== Algorithm Types ==================== */

typedef struct {
    char* name;
    char* display_name;
    char* hash_unit;
    char* profitability;
    double difficulty;
    char* block_reward;
    int32_t block_time;
} synor_mining_algorithm_t;

typedef struct {
    synor_mining_algorithm_t* algorithms;
    size_t count;
} synor_mining_algorithm_list_t;

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

typedef struct synor_mining synor_mining_t;

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

synor_mining_t* synor_mining_create(const synor_mining_config_t* config);
void synor_mining_destroy(synor_mining_t* mining);
bool synor_mining_is_closed(synor_mining_t* mining);
bool synor_mining_health_check(synor_mining_t* mining);

/* ==================== Pool Operations ==================== */

synor_mining_error_t synor_mining_connect(synor_mining_t* mining,
    const synor_pool_config_t* pool, synor_stratum_connection_t* result);
synor_mining_error_t synor_mining_disconnect(synor_mining_t* mining);
synor_mining_error_t synor_mining_get_connection(synor_mining_t* mining,
    synor_stratum_connection_t* result);
synor_mining_error_t synor_mining_get_pool_stats(synor_mining_t* mining,
    synor_pool_stats_t* result);
bool synor_mining_is_connected(synor_mining_t* mining);

void synor_stratum_connection_free(synor_stratum_connection_t* conn);
void synor_pool_stats_free(synor_pool_stats_t* stats);

/* ==================== Mining Operations ==================== */

synor_mining_error_t synor_mining_get_block_template(synor_mining_t* mining,
    synor_block_template_t* result);
synor_mining_error_t synor_mining_submit_work(synor_mining_t* mining,
    const synor_mined_work_t* work, synor_submit_result_t* result);
synor_mining_error_t synor_mining_start(synor_mining_t* mining, const char* algorithm);
synor_mining_error_t synor_mining_stop(synor_mining_t* mining);
synor_mining_error_t synor_mining_is_mining(synor_mining_t* mining, bool* result);

void synor_block_template_free(synor_block_template_t* tmpl);
void synor_submit_result_free(synor_submit_result_t* result);

/* ==================== Stats Operations ==================== */

synor_mining_error_t synor_mining_get_hashrate(synor_mining_t* mining,
    synor_hashrate_t* result);
synor_mining_error_t synor_mining_get_stats(synor_mining_t* mining,
    synor_mining_stats_t* result);
synor_mining_error_t synor_mining_get_earnings(synor_mining_t* mining,
    synor_time_period_t* period, synor_earnings_t* result);
synor_mining_error_t synor_mining_get_share_stats(synor_mining_t* mining,
    synor_share_stats_t* result);

void synor_hashrate_free(synor_hashrate_t* hashrate);
void synor_mining_stats_free(synor_mining_stats_t* stats);
void synor_earnings_free(synor_earnings_t* earnings);

/* ==================== Device Operations ==================== */

synor_mining_error_t synor_mining_list_devices(synor_mining_t* mining,
    synor_mining_device_list_t* result);
synor_mining_error_t synor_mining_get_device(synor_mining_t* mining,
    const char* device_id, synor_mining_device_t* result);
synor_mining_error_t synor_mining_set_device_config(synor_mining_t* mining,
    const char* device_id, const synor_device_config_t* config,
    synor_mining_device_t* result);
synor_mining_error_t synor_mining_enable_device(synor_mining_t* mining,
    const char* device_id);
synor_mining_error_t synor_mining_disable_device(synor_mining_t* mining,
    const char* device_id);

void synor_mining_device_free(synor_mining_device_t* device);
void synor_mining_device_list_free(synor_mining_device_list_t* list);

/* ==================== Worker Operations ==================== */

synor_mining_error_t synor_mining_list_workers(synor_mining_t* mining,
    synor_worker_info_list_t* result);
synor_mining_error_t synor_mining_get_worker(synor_mining_t* mining,
    const char* worker_id, synor_worker_info_t* result);
synor_mining_error_t synor_mining_remove_worker(synor_mining_t* mining,
    const char* worker_id);

void synor_worker_info_free(synor_worker_info_t* worker);
void synor_worker_info_list_free(synor_worker_info_list_t* list);

/* ==================== Algorithm Operations ==================== */

synor_mining_error_t synor_mining_list_algorithms(synor_mining_t* mining,
    synor_mining_algorithm_list_t* result);
synor_mining_error_t synor_mining_get_algorithm(synor_mining_t* mining,
    const char* name, synor_mining_algorithm_t* result);
synor_mining_error_t synor_mining_switch_algorithm(synor_mining_t* mining,
    const char* algorithm);
synor_mining_error_t synor_mining_get_most_profitable(synor_mining_t* mining,
    synor_mining_algorithm_t* result);

void synor_mining_algorithm_free(synor_mining_algorithm_t* algorithm);
void synor_mining_algorithm_list_free(synor_mining_algorithm_list_t* list);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_MINING_H */
