#ifndef IRC_CLIENT_H
#define IRC_CLIENT_H

#include <pthread.h>
#include <stdio.h>
#include <time.h>

#define IRC_BUFFER_SIZE 4096
#define IRC_MAX_MESSAGE 512
#define IRC_MAX_CHANNELS 50
#define IRC_MAX_USERS 200

typedef struct {
    char name[64];
    char mode;
} irc_user_t;

typedef struct {
    char name[64];
    irc_user_t users[IRC_MAX_USERS];
    int user_count;
} irc_channel_t;

typedef struct {
    char name[64];
    int enabled;
    time_t bookmarked_at;
} channel_bookmark_t;

typedef struct {
    char filename[256];
    FILE *file;
    int enabled;
} irc_logger_t;

typedef struct irc_client irc_client_t;

typedef void (*irc_message_callback)(irc_client_t *client, const char *channel, const char *nick, const char *message);
typedef void (*irc_names_callback)(irc_client_t *client, const char *channel, irc_user_t *users, int count);
typedef void (*irc_status_callback)(irc_client_t *client, const char *status);
typedef void (*irc_ctcp_callback)(irc_client_t *client, const char *sender, const char *command, const char *params);

struct irc_client {
    int socket;
    char server[256];
    int port;
    char nickname[64];
    char current_channel[64];

    int connected;
    int use_ssl;
    void *ssl_conn;

    irc_channel_t channels[IRC_MAX_CHANNELS];
    int channel_count;

    channel_bookmark_t bookmarks[IRC_MAX_CHANNELS];
    int bookmark_count;

    irc_message_callback on_message;
    irc_names_callback on_names;
    irc_status_callback on_status;
    irc_ctcp_callback on_ctcp;

    char *recv_buffer;
    int recv_buffer_size;

    int thread_active;
    pthread_t listen_thread;
    pthread_mutex_t state_lock;

    char **command_history;
    int history_count;
    int history_max;

    irc_logger_t logger;

    int registered;
    int cap_sent;
    int disconnect_reported;
    int motd_complete;
    int autojoin_pending;
    int auth_required;
    int welcome_seen;

    char last_server[256];
    int last_port;
    char last_nickname[64];
    char last_channel[64];
    int last_use_ssl;

    int reconnect_enabled;
    int reconnect_attempts;
    int reconnect_max_attempts;
    int reconnect_delay_seconds;
    time_t reconnect_next_try;
};

irc_client_t *irc_client_create(void);
void irc_client_destroy(irc_client_t *client);

int irc_client_connect(irc_client_t *client, const char *server, int port,
                       const char *nickname, const char *channel, int use_ssl);
int irc_client_disconnect(irc_client_t *client);
int irc_client_reconnect(irc_client_t *client);
void irc_client_enable_reconnect(irc_client_t *client, int enabled);
int irc_client_should_attempt_reconnect(irc_client_t *client);
int irc_client_seconds_until_reconnect(irc_client_t *client);
int irc_client_try_autojoin(irc_client_t *client);

int irc_send_command(irc_client_t *client, const char *command);
int irc_send_message(irc_client_t *client, const char *channel, const char *message);

int irc_join_channel(irc_client_t *client, const char *channel);
int irc_leave_channel(irc_client_t *client, const char *channel);
int irc_request_names(irc_client_t *client, const char *channel);

void *irc_client_listen_thread(void *arg);

int irc_logger_init(irc_logger_t *logger, const char *filename);
void irc_logger_write(irc_logger_t *logger, const char *format, ...);
void irc_logger_cleanup(irc_logger_t *logger);

int irc_bookmark_add(irc_client_t *client, const char *channel);
int irc_bookmark_remove(irc_client_t *client, const char *channel);
channel_bookmark_t *irc_bookmark_get(irc_client_t *client, int index);

void irc_send_ctcp_version(irc_client_t *client, const char *nick);
void irc_send_ctcp_time(irc_client_t *client, const char *nick);
void irc_send_ctcp_ping(irc_client_t *client, const char *nick, const char *param);

char *irc_tab_complete(irc_client_t *client, const char *prefix, int index);
void irc_add_to_history(irc_client_t *client, const char *command);

void irc_set_message_callback(irc_client_t *client, irc_message_callback callback);
void irc_set_names_callback(irc_client_t *client, irc_names_callback callback);
void irc_set_status_callback(irc_client_t *client, irc_status_callback callback);
void irc_set_ctcp_callback(irc_client_t *client, irc_ctcp_callback callback);

#endif
