#include "commands.h"
#include "features.h"
#include "gui.h"
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

// Global feature managers (to be integrated with main.c)
static network_manager_t *g_network_manager = NULL;
static filter_manager_t *g_filter_manager = NULL;
static alias_manager_t *g_alias_manager = NULL;
static dcc_manager_t *g_dcc_manager = NULL;
static reconnect_config_t g_reconnect_config;
static proxy_config_t *g_proxy_config = NULL;
static cert_validation_t *g_cert_validation = NULL;

// ============================================================================
// NETWORK COMMANDS
// ============================================================================

void cmd_network(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /network add|remove|switch|list <params>");
        return;
    }
    
    if (!g_network_manager) {
        g_network_manager = network_manager_create();
    }
    
    char *space = strchr(args, ' ');
    if (!space) {
        gui_add_notice("Invalid network command");
        return;
    }
    
    char action[32];
    strncpy(action, args, space - args);
    action[space - args] = '\0';
    
    const char *params = space + 1;
    
    if (strcasecmp(action, "add") == 0) {
        char *space2 = strchr(params, ' ');
        if (!space2) {
            gui_add_notice("Usage: /network add <name> <server> [port]");
            return;
        }
        
        char name[64];
        strncpy(name, params, space2 - params);
        name[space2 - params] = '\0';
        
        irc_client_t *new_client = irc_client_create();
        if (new_client) {
            network_manager_add(g_network_manager, name, new_client);
        }
    } else if (strcasecmp(action, "switch") == 0) {
        int index = atoi(params);
        network_manager_switch(g_network_manager, index);
    } else if (strcasecmp(action, "remove") == 0) {
        int index = atoi(params);
        network_manager_remove(g_network_manager, index);
    } else if (strcasecmp(action, "list") == 0) {
        network_manager_list(g_network_manager);
    }
}

// ============================================================================
// THEME COMMANDS
// ============================================================================

void cmd_theme(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!args || !args[0]) {
        theme_list();
        return;
    }
    
    const theme_t *theme = theme_get_by_name(args);
    if (theme) {
        theme_apply(theme);
        gui_add_notice("Theme changed to: %s", theme->name);
    } else {
        gui_add_notice("Unknown theme. Use /theme for list");
    }
}

// ============================================================================
// RECONNECT COMMANDS
// ============================================================================

void cmd_reconnect(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /reconnect enable|disable|status");
        return;
    }
    
    if (strcasecmp(args, "enable") == 0) {
        reconnect_set_enabled(&g_reconnect_config, 1);
    } else if (strcasecmp(args, "disable") == 0) {
        reconnect_set_enabled(&g_reconnect_config, 0);
    } else if (strcasecmp(args, "status") == 0) {
        gui_add_notice("Auto-reconnect: %s", g_reconnect_config.enabled ? "Enabled" : "Disabled");
        gui_add_notice("Attempts: %d/%d", g_reconnect_config.attempt_count, g_reconnect_config.max_attempts);
        gui_add_notice("Delay: %d seconds", g_reconnect_config.delay_seconds);
    }
}

// ============================================================================
// FILTER COMMANDS
// ============================================================================

void cmd_filter(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!g_filter_manager) {
        g_filter_manager = filter_manager_create();
    }
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /filter add|remove|list <pattern> [type]");
        return;
    }
    
    char *space = strchr(args, ' ');
    if (!space) {
        gui_add_notice("Invalid filter command");
        return;
    }
    
    char action[32];
    strncpy(action, args, space - args);
    action[space - args] = '\0';
    
    const char *params = space + 1;
    
    if (strcasecmp(action, "add") == 0) {
        char *space2 = strchr(params, ' ');
        int type = FILTER_IGNORE;
        
        if (space2) {
            type = atoi(space2 + 1);
            char pattern[256];
            strncpy(pattern, params, space2 - params);
            pattern[space2 - params] = '\0';
            filter_manager_add(g_filter_manager, pattern, type, "");
        } else {
            filter_manager_add(g_filter_manager, params, type, "");
        }
    } else if (strcasecmp(action, "remove") == 0) {
        int index = atoi(params);
        filter_manager_remove(g_filter_manager, index);
    } else if (strcasecmp(action, "list") == 0) {
        filter_manager_list(g_filter_manager);
    }
}

// ============================================================================
// ALIAS COMMANDS
// ============================================================================

void cmd_alias(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!g_alias_manager) {
        g_alias_manager = alias_manager_create();
    }
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /alias add|remove|list <name> [command]");
        return;
    }
    
    char *space = strchr(args, ' ');
    if (!space) {
        gui_add_notice("Invalid alias command");
        return;
    }
    
    char action[32];
    strncpy(action, args, space - args);
    action[space - args] = '\0';
    
    const char *params = space + 1;
    
    if (strcasecmp(action, "add") == 0) {
        char *space2 = strchr(params, ' ');
        if (!space2) {
            gui_add_notice("Usage: /alias add <name> <command>");
            return;
        }
        
        char name[64];
        strncpy(name, params, space2 - params);
        name[space2 - params] = '\0';
        
        alias_manager_add(g_alias_manager, name, space2 + 1);
    } else if (strcasecmp(action, "remove") == 0) {
        alias_manager_remove(g_alias_manager, params);
    } else if (strcasecmp(action, "list") == 0) {
        alias_manager_list(g_alias_manager);
    }
}

// ============================================================================
// DCC COMMANDS
// ============================================================================

void cmd_dcc(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!g_dcc_manager) {
        g_dcc_manager = dcc_manager_create();
    }
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /dcc send|receive|list|cancel <params>");
        return;
    }
    
    char *space = strchr(args, ' ');
    if (!space) {
        gui_add_notice("Invalid DCC command");
        return;
    }
    
    char action[32];
    strncpy(action, args, space - args);
    action[space - args] = '\0';
    
    const char *params = space + 1;
    
    if (strcasecmp(action, "send") == 0) {
        char *space2 = strchr(params, ' ');
        if (!space2) {
            gui_add_notice("Usage: /dcc send <nick> <file>");
            return;
        }
        
        char nick[64];
        strncpy(nick, params, space2 - params);
        nick[space2 - params] = '\0';
        
        dcc_init_send(g_dcc_manager, space2 + 1, nick);
    } else if (strcasecmp(action, "receive") == 0) {
        gui_add_notice("DCC receive: waiting for transfer offer");
    } else if (strcasecmp(action, "list") == 0) {
        dcc_manager_list(g_dcc_manager);
    } else if (strcasecmp(action, "cancel") == 0) {
        int index = atoi(params);
        dcc_manager_remove(g_dcc_manager, index);
    }
}

// ============================================================================
// PROXY COMMANDS
// ============================================================================

void cmd_proxy(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!g_proxy_config) {
        g_proxy_config = proxy_config_create();
    }
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /proxy socks5|http|disable <host>:<port>");
        return;
    }
    
    char *space = strchr(args, ' ');
    if (!space) {
        if (strcasecmp(args, "disable") == 0) {
            proxy_config_disable(g_proxy_config);
            return;
        }
        gui_add_notice("Invalid proxy command");
        return;
    }
    
    char type[32];
    strncpy(type, args, space - args);
    type[space - args] = '\0';
    
    const char *hostport = space + 1;
    char *colon = strchr(hostport, ':');
    
    if (!colon) {
        gui_add_notice("Usage: /proxy <type> <host>:<port>");
        return;
    }
    
    char host[64];
    strncpy(host, hostport, colon - hostport);
    host[colon - hostport] = '\0';
    int port = atoi(colon + 1);
    
    if (strcasecmp(type, "socks5") == 0) {
        proxy_config_set_socks5(g_proxy_config, host, port, NULL, NULL);
    } else if (strcasecmp(type, "http") == 0) {
        proxy_config_set_http(g_proxy_config, host, port);
    } else if (strcasecmp(type, "disable") == 0) {
        proxy_config_disable(g_proxy_config);
    }
}

// ============================================================================
// IPv6 COMMANDS
// ============================================================================

void cmd_ipv6(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!args || !args[0]) {
        gui_add_notice("IPv6 Support: Enabled");
        gui_add_notice("Use /connect with IPv6 addresses or hostnames");
        return;
    }
    
    const char *addr_type = ipv6_get_address_type(args);
    gui_add_notice("Address '%s' resolves to: %s", args, addr_type);
}

// ============================================================================
// CERTIFICATE VALIDATION COMMANDS
// ============================================================================

void cmd_cert(irc_client_t *client, const char *args) {
    (void)client;
    
    if (!g_cert_validation) {
        g_cert_validation = cert_validation_create();
    }
    
    if (!args || !args[0]) {
        gui_add_notice("Usage: /cert pin|verify|allow-selfsigned|ca-bundle <params>");
        return;
    }
    
    char *space = strchr(args, ' ');
    if (!space) {
        gui_add_notice("Invalid certificate command");
        return;
    }
    
    char action[32];
    strncpy(action, args, space - args);
    action[space - args] = '\0';
    
    const char *params = space + 1;
    
    if (strcasecmp(action, "pin") == 0) {
        cert_validation_pin_cert(g_cert_validation, params);
    } else if (strcasecmp(action, "verify") == 0) {
        int verify = (strcasecmp(params, "on") == 0) ? 1 : 0;
        g_cert_validation->verify_enabled = verify;
        gui_add_notice("Certificate verification: %s", verify ? "Enabled" : "Disabled");
    } else if (strcasecmp(action, "allow-selfsigned") == 0) {
        int allow = (strcasecmp(params, "yes") == 0) ? 1 : 0;
        cert_validation_allow_self_signed(g_cert_validation, allow);
    } else if (strcasecmp(action, "ca-bundle") == 0) {
        cert_validation_set_ca_bundle(g_cert_validation, params);
    }
}