#include "ubinstall-gtk.h"
// #define TIMEZONEMAP_INCLUDE
#include "timezonemap/cc-timezone-map.h"
#include "timezonemap/tz.h"

int yon_region_save(main_window *widgets){
    if (gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->RegionCombo))==-1){
        yon_ubl_status_box_spawn(GTK_CONTAINER(widgets->StatusBox),REGION_EMPTY_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
        yon_ubl_status_highlight_incorrect(widgets->RegionCombo);
        return 0;
    } else if (gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->ZoneCombo))==-1){
        yon_ubl_status_box_spawn(GTK_CONTAINER(widgets->StatusBox),ZONE_EMPTY_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
        yon_ubl_status_highlight_incorrect(widgets->ZoneCombo);
        return 0;
    } 
    if (gtk_switch_get_active(GTK_SWITCH(widgets->RegionSensitiveSwitch))){
        const char *region = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->RegionCombo));
        const char *zone = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->ZoneCombo));
        char *final = yon_char_unite(region,"/",zone,NULL);
        yon_config_register(zone_parameter,zone_parameter_command,final);
        free(final);
    } else {
        yon_config_remove_by_key(zone_parameter);
    }
    if (!main_config.configure_mode){
        yon_debug_output("%s\n",yon_config_save_args_simple(main_config.config_load_path,zone_parameter,NULL));
    }
    return 1;
}

void on_region_changed(GtkComboBox *self, main_window *widgets){
    char *active = (char*)gtk_combo_box_get_active_id(self);
    size_t size;
    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(widgets->ZoneCombo));
    if (!yon_char_is_empty(active)){
        config_str parsed = yon_timezone_get_zones_from_region(active,&size);
        for (size_t i=0;i<size;i++){
            char *timezone = yon_char_unite(active,"/",parsed[i],NULL);
            char *utc = yon_timezone_get_utc(timezone);
            if (utc&&strlen(utc)>3) utc[3]='\0';
            char *zone_label = yon_char_unite("(UTC ",utc,") ",_(parsed[i]),NULL);
            gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widgets->ZoneCombo),parsed[i],zone_label);
            free(zone_label);
            free(timezone);
        }
        if (size) yon_char_parsed_free(parsed,size);
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->ZoneCombo),0);
    }
}


gboolean on_time_zone_status_hover(GtkWidget *, GdkEvent *, main_window *widgets){
    gtk_style_context_add_class(gtk_widget_get_style_context(widgets->TimeZoneMapOverlayBox),"timezoneoverlay_hover");
    return 0;
}

gboolean on_time_zone_status_hover_end(GtkWidget *, GdkEvent *, main_window *widgets){
    gtk_style_context_remove_class(gtk_widget_get_style_context(widgets->TimeZoneMapOverlayBox),"timezoneoverlay_hover");
    return 0;
}

gboolean on_map_box_ckicked_skip(){
    return 0;
}

void on_map_selection_changed(GtkWidget *,CcTimezoneLocation *location,main_window *);

void yon_map_status_hide(main_window *widgets){
    gtk_widget_hide(widgets->TimeZoneMapOverlayBox);
}

GMutex map_source_mutex;
guint map_status_source = -1;

gboolean yon_map_status_hide_timeout(main_window *widgets){
    g_mutex_lock(&map_source_mutex);
    map_status_source=-1;
    g_mutex_unlock(&map_source_mutex);
    g_idle_add_once((GSourceOnceFunc)yon_map_status_hide,widgets);
    return G_SOURCE_REMOVE;
}

void yon_map_status_show(main_window *widgets, char *icon_name, char *title, char *title_info){
    g_mutex_lock(&map_source_mutex);
    if (map_status_source!=(guint)-1){
        g_source_remove(map_status_source);
        map_status_source=(guint)-1;
    }
    g_mutex_unlock(&map_source_mutex);
    gtk_widget_show(widgets->TimeZoneMapOverlayBox);
    gtk_label_set_text(GTK_LABEL(widgets->TimeZoneMapOverlayTitleLabel),title);
    gtk_label_set_text(GTK_LABEL(widgets->TimeZoneMapOverlayInfoLabel),title_info);
    if (!yon_char_is_empty(icon_name)){
        gtk_widget_show(widgets->TimeZoneMapOverlayImage);
            widgets->TimeZoneMapOverlayImage = gtk_image_new_from_icon_name(icon_path,GTK_ICON_SIZE_BUTTON);
            gtk_image_set_pixel_size(GTK_IMAGE(widgets->TimeZoneMapOverlayImage),48);
    } else {
        gtk_widget_hide(widgets->TimeZoneMapOverlayImage);
    }
    g_mutex_lock(&map_source_mutex);
    map_status_source = g_timeout_add_seconds(3,(GSourceFunc)yon_map_status_hide_timeout,widgets);
    g_mutex_unlock(&map_source_mutex);
}

void on_zone_changed(GtkWidget *, main_window *widgets){
    // g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionMapTarget),G_CALLBACK(on_map_selection_changed),widgets);

    const char *region = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->RegionCombo));
    const char *zone = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->ZoneCombo));
    if (!yon_char_is_empty(region)&&!yon_char_is_empty(zone)){
        char *timezone = yon_char_unite(region,"/",zone,NULL);
        yon_map_update(widgets,timezone);
        free(timezone);
    }
    // g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionMapTarget),G_CALLBACK(on_map_selection_changed),widgets);
}

void on_map_selection_changed(GtkWidget *,CcTimezoneLocation *location,main_window *widgets){
    if (!location) return;
    g_signal_handlers_block_by_func(G_OBJECT(widgets->ZoneCombo),G_CALLBACK(on_zone_changed),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionMapTarget),G_CALLBACK(on_map_selection_changed),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionEntry),G_CALLBACK(on_region_entry_changed),widgets);
    char *zone = yon_char_new(cc_timezone_location_get_zone(location));
    char *region = yon_char_divide_search(zone,"/",-1);
    

    char *timezone = (char*)cc_timezone_location_get_zone(location);
    GtkTreeIter iter;
    for_iter(widgets->RegionTimezoneCompletionList,&iter){
        char *render, *tz;
        gtk_tree_model_get(GTK_TREE_MODEL(widgets->RegionTimezoneCompletionList),&iter,0,&render,1,&tz,-1);
        if (!strcmp(timezone,tz)){
            gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->RegionCombo),region);
            while(gtk_events_pending()) gtk_main_iteration();
            gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->ZoneCombo),zone);
            gtk_entry_set_text(GTK_ENTRY(widgets->RegionEntry),render);
            char *utc = yon_timezone_get_utc(tz);
            yon_map_status_show(widgets,NULL,MAP_TITLE_LABEL(utc),render);
            break;

        }
    }
    if (!yon_char_is_empty(region)) free(region);
    g_signal_handlers_unblock_by_func(G_OBJECT(widgets->ZoneCombo),G_CALLBACK(on_zone_changed),widgets);
    g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionMapTarget),G_CALLBACK(on_map_selection_changed),widgets);
    g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionEntry),G_CALLBACK(on_region_entry_changed),widgets);
}

void yon_map_update(main_window *widgets, const char *timezone){
        g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionMapTarget),G_CALLBACK(on_map_selection_changed),widgets);
        g_signal_handlers_block_by_func(G_OBJECT(widgets->ZoneCombo),G_CALLBACK(on_zone_changed),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionEntry),G_CALLBACK(on_region_entry_changed),widgets);
    textdomain(timezone_locale_name);
    char *region = yon_timezone_get_zone(timezone);
    char *country = yon_timezone_get_country(timezone);
    char *city = yon_timezone_get_city(timezone);
    char *zone_name = yon_char_unite(_(city),", ", _(country),NULL);
    textdomain(LocaleName);
    gtk_entry_set_text(GTK_ENTRY(widgets->RegionEntry),zone_name);

    gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->RegionCombo),region);
    gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->ZoneCombo),city);
        cc_timezone_map_set_timezone(CC_TIMEZONE_MAP(widgets->RegionMapTarget),timezone);
    g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionEntry),G_CALLBACK(on_region_entry_changed),widgets);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->ZoneCombo),G_CALLBACK(on_zone_changed),widgets);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionMapTarget),G_CALLBACK(on_map_selection_changed),widgets);
        textdomain(LocaleName);
}

void on_region_entry_changed(GtkWidget *, main_window *widgets){
    GtkTreeIter iter;
    int found = 0;
    for_iter(widgets->RegionTimezoneCompletionList, &iter){
        char *target, *timezone;
        gtk_tree_model_get(GTK_TREE_MODEL(widgets->RegionTimezoneCompletionList),&iter,0,&target,1,&timezone,-1);
        char *target_entry = (char*)gtk_entry_get_text(GTK_ENTRY(widgets->RegionEntry));
        if (!strcmp(target,target_entry)){
            g_object_set_data(G_OBJECT(widgets->RegionEntry),zone_parameter,yon_char_new(timezone));
            yon_map_update(widgets,timezone);
            found = 1;

        }
    }
    if (!found){
        g_object_set_data(G_OBJECT(widgets->RegionEntry),zone_parameter,NULL);
    }
}

// void yon_region_load(CcTimezoneLocation *target, main_window *widgets){
//     const char *timezone = cc_timezone_location_get_zone(target);
    
// }

void yon_region_init(main_window *widgets){
    if (!main_config.configure_mode){
        yon_config_update_by_args(main_config.config_load_path, zone_parameter,NULL);
    }
    yon_timezone_init();
    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(widgets->RegionCombo));
    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(widgets->KeyboardNumLockCombo));
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->RegionMapBox));
    if (list){
        GList *iter;
        for (iter = list; iter; iter=iter->next){
            gtk_widget_destroy(iter->data);
        }
        g_list_free(list);
    }
    widgets->RegionMapTarget = GTK_WIDGET(cc_timezone_map_new());
    gtk_box_pack_start(GTK_BOX(widgets->RegionMapBox),GTK_WIDGET(widgets->RegionMapTarget),1,1,0);
    g_signal_connect(G_OBJECT(widgets->RegionMapTarget),"location-changed",G_CALLBACK(on_map_selection_changed),widgets);
    gtk_widget_show(GTK_WIDGET(widgets->RegionMapTarget));
    char *config_param = config(zone_parameter);
    if (!yon_char_is_empty(config_param)){
        cc_timezone_map_set_timezone(CC_TIMEZONE_MAP(widgets->RegionMapTarget),config_param);
    }

    size_t size=0;
    GtkTreeIter iter;
    config_str parsed = yon_timezone_get_all(&size);
    bind_textdomain_codeset(timezone_locale_name,"UTF-8");
    textdomain(timezone_locale_name);
    GHashTable *timezones_list = g_hash_table_new(g_str_hash,g_str_equal);
    for (size_t i=0;i<size;i++){
        char *zone_country = yon_timezone_get_country(parsed[i]);
        char *zone_city = yon_timezone_get_city(parsed[i]);
        char *zone = yon_timezone_get_zone(parsed[i]);
        char *zone_name = yon_char_unite(_(zone_city),", ", _(zone_country),NULL);
        char *zone_name_original = yon_char_unite(zone_city,", ", zone_country,NULL);
        gtk_list_store_append(widgets->RegionTimezoneCompletionList,&iter);
        gtk_list_store_set(widgets->RegionTimezoneCompletionList,&iter,0,zone_name,1,parsed[i],-1);
        gtk_list_store_append(widgets->RegionTimezoneCompletionList,&iter);
        gtk_list_store_set(widgets->RegionTimezoneCompletionList,&iter,0,zone_name_original,1,parsed[i],-1);
        g_hash_table_add(timezones_list,yon_char_new(zone));
    }
    yon_char_parsed_free(parsed,size);

    size_t zones_size=0;
    config_str keys = (config_str)g_hash_table_get_keys_as_array(timezones_list,(guint*)&zones_size);
    // TzDB *db = tz_load_db();
    // GPtrArray *locations = tz_get_locations(db);
    // g_ptr_array_foreach(locations,(GFunc)yon_region_load,widgets);
    qsort(keys,zones_size,sizeof(char*),(__compar_fn_t)yon_char_parsed_compare);
    for (size_t i=0;i<zones_size;i++){
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widgets->RegionCombo),keys[i],_(keys[i]));
    }
    yon_char_parsed_free(keys,zones_size);
    textdomain(LocaleName);
        while(gtk_events_pending()) gtk_main_iteration();
    gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->RegionCombo),0);
    char *zone = yon_char_new(config(zone_parameter));

    if (!yon_char_is_empty(zone)){
        char *timezone = yon_char_divide_search(zone,"/",-1);
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->RegionCombo),timezone);
        while(gtk_events_pending()) gtk_main_iteration();
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->ZoneCombo),zone);
        gtk_switch_set_active(GTK_SWITCH(widgets->RegionSensitiveSwitch),1);
        free(timezone);
    } else {
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->RegionCombo),0);
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->ZoneCombo),0);
        gtk_switch_set_active(GTK_SWITCH(widgets->RegionSensitiveSwitch),0);
    }
    if (!gtk_switch_get_active(GTK_SWITCH(widgets->RegionSensitiveSwitch))){
        size=0;
        config_str autotimezone = yon_config_load(internet_tomezone_check_command,(int*)&size);
        if (autotimezone&&!yon_char_is_empty(autotimezone[0])){
            yon_char_remove_last_symbol(autotimezone[0],'\n');
            gtk_entry_set_text(GTK_ENTRY(widgets->RegionEntry),autotimezone[0]);
            cc_timezone_map_set_timezone(CC_TIMEZONE_MAP(widgets->RegionMapTarget),autotimezone[0]);
        }
    }
}