/**
 * @file database.h
 * @brief Synor Database SDK for C
 *
 * Multi-model database with Key-Value, Document, Vector, and Time Series stores.
 */

#ifndef SYNOR_DATABASE_H
#define SYNOR_DATABASE_H

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

#ifdef __cplusplus
extern "C" {
#endif

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

typedef enum {
    SYNOR_DB_OK = 0,
    SYNOR_DB_ERROR_CLIENT_CLOSED,
    SYNOR_DB_ERROR_NETWORK,
    SYNOR_DB_ERROR_HTTP,
    SYNOR_DB_ERROR_ENCODING,
    SYNOR_DB_ERROR_DECODING,
    SYNOR_DB_ERROR_INVALID_RESPONSE,
    SYNOR_DB_ERROR_MEMORY,
    SYNOR_DB_ERROR_UNKNOWN
} synor_db_error_t;

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

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

/* ==================== Key-Value Types ==================== */

typedef struct {
    char* key;
    char* value;         /* JSON string */
    int32_t ttl;
    int64_t created_at;
    int64_t updated_at;
} synor_kv_entry_t;

typedef struct {
    synor_kv_entry_t* items;
    size_t count;
} synor_kv_list_t;

/* ==================== Document Types ==================== */

typedef struct {
    char* id;
    char* collection;
    char* data;          /* JSON string */
    int64_t created_at;
    int64_t updated_at;
} synor_document_t;

typedef struct {
    synor_document_t* documents;
    size_t count;
} synor_document_list_t;

typedef struct {
    const char* filter;  /* JSON string */
    const char* sort;    /* JSON string */
    int32_t limit;
    int32_t offset;
} synor_document_query_t;

/* ==================== Vector Types ==================== */

typedef struct {
    const char* id;
    const double* vector;
    size_t vector_size;
    const char* metadata;  /* JSON string, optional */
} synor_vector_entry_t;

typedef struct {
    char* id;
    double score;
    double* vector;
    size_t vector_size;
    char* metadata;
} synor_search_result_t;

typedef struct {
    synor_search_result_t* results;
    size_t count;
} synor_search_result_list_t;

/* ==================== Time Series Types ==================== */

typedef struct {
    int64_t timestamp;
    double value;
    const char* tags;   /* JSON string, optional */
} synor_data_point_t;

typedef struct {
    int64_t start;
    int64_t end;
} synor_time_range_t;

typedef struct {
    const char* function;  /* avg, sum, min, max, count */
    const char* interval;  /* 1m, 5m, 1h, 1d */
} synor_aggregation_t;

typedef struct {
    synor_data_point_t* points;
    size_t count;
} synor_data_point_list_t;

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

typedef struct synor_database synor_database_t;

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

/**
 * Create a new database client.
 */
synor_database_t* synor_database_create(const synor_db_config_t* config);

/**
 * Destroy the database client and free resources.
 */
void synor_database_destroy(synor_database_t* db);

/**
 * Check if the client is closed.
 */
bool synor_database_is_closed(synor_database_t* db);

/**
 * Perform a health check.
 */
bool synor_database_health_check(synor_database_t* db);

/* ==================== Key-Value Operations ==================== */

/**
 * Get a value by key.
 * Caller must free result->value.
 */
synor_db_error_t synor_kv_get(synor_database_t* db, const char* key, char** value);

/**
 * Set a value for a key.
 */
synor_db_error_t synor_kv_set(synor_database_t* db, const char* key,
    const char* value, int32_t ttl);

/**
 * Delete a key.
 */
synor_db_error_t synor_kv_delete(synor_database_t* db, const char* key);

/**
 * List keys by prefix.
 * Caller must free result with synor_kv_list_free.
 */
synor_db_error_t synor_kv_list(synor_database_t* db, const char* prefix,
    synor_kv_list_t* result);

/**
 * Free a key-value list.
 */
void synor_kv_list_free(synor_kv_list_t* list);

/* ==================== Document Operations ==================== */

/**
 * Create a document.
 * Caller must free returned id.
 */
synor_db_error_t synor_doc_create(synor_database_t* db, const char* collection,
    const char* document, char** id);

/**
 * Get a document by ID.
 * Caller must free result with synor_document_free.
 */
synor_db_error_t synor_doc_get(synor_database_t* db, const char* collection,
    const char* id, synor_document_t* result);

/**
 * Update a document.
 */
synor_db_error_t synor_doc_update(synor_database_t* db, const char* collection,
    const char* id, const char* update);

/**
 * Delete a document.
 */
synor_db_error_t synor_doc_delete(synor_database_t* db, const char* collection,
    const char* id);

/**
 * Query documents.
 * Caller must free result with synor_document_list_free.
 */
synor_db_error_t synor_doc_query(synor_database_t* db, const char* collection,
    const synor_document_query_t* query, synor_document_list_t* result);

/**
 * Free a document.
 */
void synor_document_free(synor_document_t* doc);

/**
 * Free a document list.
 */
void synor_document_list_free(synor_document_list_t* list);

/* ==================== Vector Operations ==================== */

/**
 * Upsert vectors.
 */
synor_db_error_t synor_vector_upsert(synor_database_t* db, const char* collection,
    const synor_vector_entry_t* vectors, size_t count);

/**
 * Search for similar vectors.
 * Caller must free result with synor_search_result_list_free.
 */
synor_db_error_t synor_vector_search(synor_database_t* db, const char* collection,
    const double* vector, size_t vector_size, int32_t k,
    synor_search_result_list_t* result);

/**
 * Delete vectors by IDs.
 */
synor_db_error_t synor_vector_delete(synor_database_t* db, const char* collection,
    const char** ids, size_t count);

/**
 * Free search results.
 */
void synor_search_result_list_free(synor_search_result_list_t* list);

/* ==================== Time Series Operations ==================== */

/**
 * Write data points.
 */
synor_db_error_t synor_ts_write(synor_database_t* db, const char* series,
    const synor_data_point_t* points, size_t count);

/**
 * Query data points.
 * Caller must free result with synor_data_point_list_free.
 */
synor_db_error_t synor_ts_query(synor_database_t* db, const char* series,
    const synor_time_range_t* range, const synor_aggregation_t* aggregation,
    synor_data_point_list_t* result);

/**
 * Free data point list.
 */
void synor_data_point_list_free(synor_data_point_list_t* list);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_DATABASE_H */
