#ifndef CONFIG_H
#define CONFIG_H

#include <sqlite3.h>
#include <cjson/cJSON.h>
#include <time.h>
#include <pthread.h>

// Forward declaration for WebSocket support
struct lws;

// Configuration constants
#define CONFIG_VALUE_MAX_LENGTH 1024
#define RELAY_NAME_MAX_LENGTH 256
#define RELAY_DESCRIPTION_MAX_LENGTH 512
#define RELAY_URL_MAX_LENGTH 512
#define RELAY_PUBKEY_MAX_LENGTH 65
#define RELAY_CONTACT_MAX_LENGTH 256
#define SUBSCRIPTION_ID_MAX_LENGTH 64
#define CLIENT_IP_MAX_LENGTH 46
#define MAX_SUBSCRIPTIONS_PER_CLIENT 25
#define MAX_TOTAL_SUBSCRIPTIONS 5000
#define MAX_FILTERS_PER_SUBSCRIPTION 10
#define DEFAULT_PORT 8888
#define DEFAULT_DATABASE_PATH "db/c_nostr_relay.db"

// Database path for event-based config
extern char g_database_path[512];

// Command line options structure for first-time startup
typedef struct {
    int port_override;  // -1 = not set, >0 = port value
    char admin_pubkey_override[65];   // Empty string = not set, 64-char hex = override
    char relay_privkey_override[65];  // Empty string = not set, 64-char hex = override
    int strict_port;  // 0 = allow port increment, 1 = fail if exact port unavailable
    int debug_level;  // 0-5, default 0 (no debug output)
} cli_options_t;

// Core configuration functions (temporary compatibility)
int init_configuration_system(const char* config_dir_override, const char* config_file_override);
void cleanup_configuration_system(void);

// Database config functions (temporary compatibility)
int set_database_config(const char* key, const char* value, const char* changed_by);

// Database functions
char* get_database_name_from_relay_pubkey(const char* relay_pubkey);
int create_database_with_relay_pubkey(const char* relay_pubkey);

// Configuration event functions
int store_config_event_in_database(const cJSON* event);
cJSON* load_config_event_from_database(const char* relay_pubkey);
int process_configuration_event(const cJSON* event);
int handle_configuration_event(cJSON* event, char* error_message, size_t error_size);

// Retry storing initial config event after database initialization
int retry_store_initial_config_event(void);

// Configuration access functions
const char* get_config_value(const char* key);
int get_config_int(const char* key, int default_value);
int get_config_bool(const char* key, int default_value);

// First-time startup functions
int is_first_time_startup(void);
int first_time_startup_sequence(const cli_options_t* cli_options, char* admin_pubkey_out, char* relay_pubkey_out, char* relay_privkey_out);
int startup_existing_relay(const char* relay_pubkey, const cli_options_t* cli_options);

// Configuration application functions
int apply_configuration_from_event(const cJSON* event);
int apply_runtime_config_handlers(const cJSON* old_event, const cJSON* new_event);

// Utility functions
char** find_existing_db_files(void);
char* extract_pubkey_from_filename(const char* filename);

// Secure relay private key storage functions
int store_relay_private_key(const char* relay_privkey_hex);
char* get_relay_private_key(void);
const char* get_temp_relay_private_key(void);  // For first-time startup only

// NIP-42 authentication configuration functions
int parse_auth_required_kinds(const char* kinds_str, int* kinds_array, int max_kinds);
int is_nip42_auth_required_for_kind(int event_kind);
int is_nip42_auth_globally_required(void);

// ================================
// NEW ADMIN API FUNCTIONS
// ================================

// Config table management functions (config table created via embedded schema)
const char* get_config_value_from_table(const char* key);
int set_config_value_in_table(const char* key, const char* value, const char* data_type,
                              const char* description, const char* category, int requires_restart);
int update_config_in_table(const char* key, const char* value);
int populate_default_config_values(void);
int populate_all_config_values_atomic(const char* admin_pubkey, const char* relay_pubkey);
int add_pubkeys_to_config_table(void);

// Admin event processing functions (updated with WebSocket support)
int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
int process_admin_config_event(cJSON* event, char* error_message, size_t error_size);
int process_admin_auth_event(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);

// Unified Kind 23456 handler functions
int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
int handle_auth_query_unified(cJSON* event, const char* query_type, char* error_message, size_t error_size, struct lws* wsi);
int handle_system_command_unified(cJSON* event, const char* command, char* error_message, size_t error_size, struct lws* wsi);
int handle_auth_rule_modification_unified(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);

// Admin response functions
int send_admin_response_event(const cJSON* response_data, const char* recipient_pubkey, struct lws* wsi);
cJSON* build_query_response(const char* query_type, cJSON* results_array, int total_count);

// Auth rules management functions
int add_auth_rule_from_config(const char* rule_type, const char* pattern_type,
                             const char* pattern_value);
int remove_auth_rule_from_config(const char* rule_type, const char* pattern_type,
                                const char* pattern_value);

// Unified configuration cache management
void force_config_cache_refresh(void);
const char* get_admin_pubkey_cached(void);
const char* get_relay_pubkey_cached(void);
void invalidate_config_cache(void);
int reload_config_from_table(void);

// Hybrid config access functions
const char* get_config_value_hybrid(const char* key);
int is_config_table_ready(void);

// Migration support functions
int initialize_config_system_with_migration(void);
int migrate_config_from_events_to_table(void);
int populate_config_table_from_event(const cJSON* event);

// Startup configuration processing functions
int process_startup_config_event(const cJSON* event);
int process_startup_config_event_with_fallback(const cJSON* event);

// Atomic CLI override application
int apply_cli_overrides_atomic(const cli_options_t* cli_options);

// Dynamic event generation functions for WebSocket configuration fetching
cJSON* generate_config_event_from_table(void);
int req_filter_requests_config_events(const cJSON* filter);
cJSON* generate_synthetic_config_event_for_subscription(const char* sub_id, const cJSON* filters);
char* generate_config_event_json(void);

#endif /* CONFIG_H */