/**
 * @file economics.h
 * @brief Synor Economics SDK for C
 *
 * Pricing, billing, staking, and discount management.
 */

#ifndef SYNOR_ECONOMICS_H
#define SYNOR_ECONOMICS_H

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

#ifdef __cplusplus
extern "C" {
#endif

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

typedef enum {
    SYNOR_ECONOMICS_OK = 0,
    SYNOR_ECONOMICS_ERROR_CLIENT_CLOSED,
    SYNOR_ECONOMICS_ERROR_NETWORK,
    SYNOR_ECONOMICS_ERROR_HTTP,
    SYNOR_ECONOMICS_ERROR_ENCODING,
    SYNOR_ECONOMICS_ERROR_DECODING,
    SYNOR_ECONOMICS_ERROR_INVALID_RESPONSE,
    SYNOR_ECONOMICS_ERROR_MEMORY,
    SYNOR_ECONOMICS_ERROR_TIMEOUT,
    SYNOR_ECONOMICS_ERROR_UNKNOWN
} synor_economics_error_t;

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

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

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

typedef enum {
    SYNOR_SERVICE_COMPUTE,
    SYNOR_SERVICE_STORAGE,
    SYNOR_SERVICE_DATABASE,
    SYNOR_SERVICE_HOSTING,
    SYNOR_SERVICE_RPC,
    SYNOR_SERVICE_BRIDGE
} synor_service_type_t;

typedef enum {
    SYNOR_BILLING_HOURLY,
    SYNOR_BILLING_DAILY,
    SYNOR_BILLING_WEEKLY,
    SYNOR_BILLING_MONTHLY
} synor_billing_period_t;

typedef enum {
    SYNOR_STAKE_ACTIVE,
    SYNOR_STAKE_UNSTAKING,
    SYNOR_STAKE_WITHDRAWN
} synor_stake_status_t;

typedef enum {
    SYNOR_DISCOUNT_PERCENTAGE,
    SYNOR_DISCOUNT_FIXED,
    SYNOR_DISCOUNT_CREDITS
} synor_discount_type_t;

typedef enum {
    SYNOR_INVOICE_PENDING,
    SYNOR_INVOICE_PAID,
    SYNOR_INVOICE_OVERDUE,
    SYNOR_INVOICE_CANCELLED
} synor_invoice_status_t;

/* ==================== Pricing Types ==================== */

typedef struct {
    synor_service_type_t service;
    char* unit;
    char* price_per_unit;
    char* currency;
    double minimum;
    double maximum;
} synor_service_pricing_t;

typedef struct {
    synor_service_pricing_t* prices;
    size_t count;
} synor_service_pricing_list_t;

typedef struct {
    synor_service_type_t service;
    double compute_units;
    double storage_bytes;
    double bandwidth_bytes;
    int64_t duration_seconds;
    int32_t requests;
} synor_usage_metrics_t;

typedef struct {
    synor_service_type_t service;
    char* amount;
    char* currency;
    synor_usage_metrics_t usage;
} synor_price_result_t;

typedef struct {
    synor_service_type_t service;
    synor_usage_metrics_t projected_usage;
    synor_billing_period_t period;
} synor_usage_plan_item_t;

typedef struct {
    synor_usage_plan_item_t* items;
    size_t count;
} synor_usage_plan_t;

typedef struct {
    synor_service_type_t service;
    char* amount;
} synor_cost_item_t;

typedef struct {
    char* total;
    char* currency;
    synor_cost_item_t* breakdown;
    size_t breakdown_count;
    char* discount_applied;
    synor_billing_period_t period;
} synor_cost_estimate_t;

/* ==================== Billing Types ==================== */

typedef struct {
    synor_service_type_t service;
    double compute_units;
    double storage_bytes;
    double bandwidth_bytes;
    int32_t requests;
    char* cost;
} synor_usage_item_t;

typedef struct {
    synor_billing_period_t period;
    int64_t start_date;
    int64_t end_date;
    synor_usage_item_t* items;
    size_t items_count;
    char* total_cost;
    char* currency;
} synor_usage_t;

typedef struct {
    char* service;
    char* description;
    int32_t quantity;
    char* unit_price;
    char* amount;
} synor_invoice_line_t;

typedef struct {
    char* id;
    int64_t date;
    int64_t due_date;
    synor_invoice_status_t status;
    synor_invoice_line_t* lines;
    size_t lines_count;
    char* subtotal;
    char* discount;
    char* tax;
    char* total;
    char* currency;
    char* pdf_url;
} synor_invoice_t;

typedef struct {
    synor_invoice_t* invoices;
    size_t count;
} synor_invoice_list_t;

typedef struct {
    char* available;
    char* pending;
    char* staked;
    char* total;
    char* currency;
} synor_account_balance_t;

/* ==================== Staking Types ==================== */

typedef struct {
    char* id;
    char* amount;
    int64_t staked_at;
    int64_t unlock_at;
    synor_stake_status_t status;
    char* rewards_earned;
    double apy;
} synor_stake_t;

typedef struct {
    synor_stake_t* stakes;
    size_t count;
} synor_stake_list_t;

typedef struct {
    char* id;
    char* amount;
    char* tx_hash;
    int64_t staked_at;
    int64_t unlock_at;
    double apy;
} synor_stake_receipt_t;

typedef struct {
    char* id;
    char* amount;
    char* tx_hash;
    int64_t unstaked_at;
    int64_t available_at;
} synor_unstake_receipt_t;

typedef struct {
    char* pending;
    char* claimed;
    char* total;
    double current_apy;
    int64_t last_claim;
    int64_t next_distribution;
} synor_staking_rewards_t;

/* ==================== Discount Types ==================== */

typedef struct {
    char* code;
    synor_discount_type_t type;
    char* value;
    char* description;
    synor_service_type_t* applicable_services;
    size_t applicable_services_count;
    int64_t valid_from;
    int64_t valid_until;
    int32_t max_uses;
    int32_t current_uses;
    bool active;
} synor_discount_t;

typedef struct {
    synor_discount_t* discounts;
    size_t count;
} synor_discount_list_t;

typedef struct {
    synor_discount_t discount;
    char* savings_estimate;
    int64_t applied_at;
} synor_discount_result_t;

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

typedef struct synor_economics synor_economics_t;

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

synor_economics_t* synor_economics_create(const synor_economics_config_t* config);
void synor_economics_destroy(synor_economics_t* economics);
bool synor_economics_is_closed(synor_economics_t* economics);
bool synor_economics_health_check(synor_economics_t* economics);

/* ==================== Pricing Operations ==================== */

synor_economics_error_t synor_economics_get_pricing(synor_economics_t* economics,
    synor_service_type_t* service, synor_service_pricing_list_t* result);
synor_economics_error_t synor_economics_get_price(synor_economics_t* economics,
    synor_service_type_t service, const synor_usage_metrics_t* usage,
    synor_price_result_t* result);
synor_economics_error_t synor_economics_estimate_cost(synor_economics_t* economics,
    const synor_usage_plan_t* plan, synor_cost_estimate_t* result);

void synor_service_pricing_free(synor_service_pricing_t* pricing);
void synor_service_pricing_list_free(synor_service_pricing_list_t* list);
void synor_price_result_free(synor_price_result_t* result);
void synor_cost_estimate_free(synor_cost_estimate_t* estimate);

/* ==================== Billing Operations ==================== */

synor_economics_error_t synor_economics_get_usage(synor_economics_t* economics,
    synor_billing_period_t* period, synor_usage_t* result);
synor_economics_error_t synor_economics_get_invoices(synor_economics_t* economics,
    synor_invoice_list_t* result);
synor_economics_error_t synor_economics_get_invoice(synor_economics_t* economics,
    const char* invoice_id, synor_invoice_t* result);
synor_economics_error_t synor_economics_get_balance(synor_economics_t* economics,
    synor_account_balance_t* result);

void synor_usage_free(synor_usage_t* usage);
void synor_invoice_free(synor_invoice_t* invoice);
void synor_invoice_list_free(synor_invoice_list_t* list);
void synor_account_balance_free(synor_account_balance_t* balance);

/* ==================== Staking Operations ==================== */

synor_economics_error_t synor_economics_stake(synor_economics_t* economics,
    const char* amount, int32_t duration_days, synor_stake_receipt_t* result);
synor_economics_error_t synor_economics_unstake(synor_economics_t* economics,
    const char* stake_id, synor_unstake_receipt_t* result);
synor_economics_error_t synor_economics_get_stakes(synor_economics_t* economics,
    synor_stake_list_t* result);
synor_economics_error_t synor_economics_get_stake(synor_economics_t* economics,
    const char* stake_id, synor_stake_t* result);
synor_economics_error_t synor_economics_get_staking_rewards(synor_economics_t* economics,
    synor_staking_rewards_t* result);
synor_economics_error_t synor_economics_claim_rewards(synor_economics_t* economics,
    synor_stake_receipt_t* result);

void synor_stake_free(synor_stake_t* stake);
void synor_stake_list_free(synor_stake_list_t* list);
void synor_stake_receipt_free(synor_stake_receipt_t* receipt);
void synor_unstake_receipt_free(synor_unstake_receipt_t* receipt);
void synor_staking_rewards_free(synor_staking_rewards_t* rewards);

/* ==================== Discount Operations ==================== */

synor_economics_error_t synor_economics_apply_discount(synor_economics_t* economics,
    const char* code, synor_discount_result_t* result);
synor_economics_error_t synor_economics_remove_discount(synor_economics_t* economics,
    const char* code);
synor_economics_error_t synor_economics_get_discounts(synor_economics_t* economics,
    synor_discount_list_t* result);

void synor_discount_free(synor_discount_t* discount);
void synor_discount_list_free(synor_discount_list_t* list);
void synor_discount_result_free(synor_discount_result_t* result);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_ECONOMICS_H */
