#include "downloads/download_window.h"
#include <stdio.h>

static GtkWidget *download_window = NULL;
static GtkListStore *download_store = NULL;
static GtkWidget *tree_view = NULL;

// Columns for the tree view
enum {
  COL_FILENAME,
  COL_PROGRESS,
  COL_SPEED,
  COL_ETA,
  COL_MULTIPART,
  COL_STATUS,
  COL_DOWNLOAD_PTR, // Hidden column to store Download*
  NUM_COLS
};

// Format bytes to human readable string
static char *format_size(double size) {
  const char *units[] = {"B", "KB", "MB", "GB", "TB"};
  int i = 0;
  while (size >= 1024 && i < 4) {
    size /= 1024;
    i++;
  }
  return g_strdup_printf("%.1f %s", size, units[i]);
}

// Format time to human readable string
static char *format_time(double seconds) {
  if (seconds < 60) {
    return g_strdup_printf("%.0fs", seconds);
  } else if (seconds < 3600) {
    return g_strdup_printf("%.0fm %ds", seconds / 60, (int)seconds % 60);
  } else {
    return g_strdup_printf("%.0fh %dm", seconds / 3600,
                           ((int)seconds % 3600) / 60);
  }
}

// Callback for Pause/Resume button click
static void on_control_clicked(GtkCellRenderer *renderer, gchar *path_str,
                               gpointer user_data) {
  GtkTreeIter iter;
  if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(download_store), &iter,
                                          path_str)) {
    Download *download;
    gtk_tree_model_get(GTK_TREE_MODEL(download_store), &iter, COL_DOWNLOAD_PTR,
                       &download, -1);

    if (download->state == DOWNLOAD_STATE_DOWNLOADING) {
      download_pause(download);
    } else if (download->state == DOWNLOAD_STATE_PAUSED) {
      download_resume(download);
    }
    download_window_update();
  }
}

// Callback for Cancel button click
static void on_cancel_clicked(GtkCellRenderer *renderer, gchar *path_str,
                              gpointer user_data) {
  GtkTreeIter iter;
  if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(download_store), &iter,
                                          path_str)) {
    Download *download;
    gtk_tree_model_get(GTK_TREE_MODEL(download_store), &iter, COL_DOWNLOAD_PTR,
                       &download, -1);

    download_cancel(download);
    download_window_update();
  }
}

static void create_view_and_model(void) {
  download_store = gtk_list_store_new(NUM_COLS,
                                      G_TYPE_STRING, // Filename
                                      G_TYPE_INT,    // Progress (percentage)
                                      G_TYPE_STRING, // Speed
                                      G_TYPE_STRING, // ETA
                                      G_TYPE_STRING, // Multipart
                                      G_TYPE_STRING, // Status
                                      G_TYPE_POINTER // Download*
  );

  tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(download_store));

  // Filename Column
  GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
  GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(
      "Filename", renderer, "text", COL_FILENAME, NULL);
  gtk_tree_view_column_set_resizable(column, TRUE);
  gtk_tree_view_column_set_min_width(column, 200);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  // Progress Column
  renderer = gtk_cell_renderer_progress_new();
  column = gtk_tree_view_column_new_with_attributes(
      "Progress", renderer, "value", COL_PROGRESS, NULL);
  gtk_tree_view_column_set_min_width(column, 150);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  // Speed Column
  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("Speed", renderer, "text",
                                                    COL_SPEED, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  // ETA Column
  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("ETA", renderer, "text",
                                                    COL_ETA, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  // Multipart Column
  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("Parts", renderer, "text",
                                                    COL_MULTIPART, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  // Status Column
  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("Status", renderer, "text",
                                                    COL_STATUS, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  // Controls Column (Pause/Resume)
  // Note: In a real app we'd use icons, but for simplicity we'll use text
  // buttons via GtkCellRendererText with "edited" signal or similar, but
  // standard GtkCellRendererText doesn't support button clicks easily. Instead,
  // we'll use a simple approach: Double click row to toggle pause? Or better:
  // Add a "Action" text column that says "[Pause]" or "[Resume]" and handle
  // click. For this implementation, let's use a simple text column that acts as
  // a button via 'row-activated' or similar is tricky for specific cells. We
  // will use GtkCellRendererPixbuf if we had icons, but we don't have
  // guaranteed icons. Let's stick to a simple text column "Action" and handle
  // selection change or row activation.

  // Actually, let's just use row activation (double click) to Pause/Resume for
  // now to keep it simple and robust without custom cell renderers. And a
  // right-click menu for Cancel.

  g_object_unref(download_store); // Tree view holds a reference
}

// Row activated handler (Double click)
static void on_row_activated(GtkTreeView *tree_view, GtkTreePath *path,
                             GtkTreeViewColumn *column, gpointer user_data) {
  GtkTreeIter iter;
  if (gtk_tree_model_get_iter(GTK_TREE_MODEL(download_store), &iter, path)) {
    Download *download;
    gtk_tree_model_get(GTK_TREE_MODEL(download_store), &iter, COL_DOWNLOAD_PTR,
                       &download, -1);

    if (download->state == DOWNLOAD_STATE_DOWNLOADING) {
      download_pause(download);
    } else if (download->state == DOWNLOAD_STATE_PAUSED) {
      download_resume(download);
    }
    download_window_update();
  }
}

// Popup menu for Cancel
static void on_cancel_menu_item_clicked(GtkMenuItem *item, gpointer user_data) {
  Download *download = (Download *)user_data;
  download_cancel(download);
  download_window_update();
}

static gboolean on_button_press(GtkWidget *widget, GdkEventButton *event,
                                gpointer user_data) {
  if (event->type == GDK_BUTTON_PRESS && event->button == 3) { // Right click
    GtkTreeSelection *selection =
        gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
    GtkTreeIter iter;
    GtkTreeModel *model;

    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
      Download *download;
      gtk_tree_model_get(model, &iter, COL_DOWNLOAD_PTR, &download, -1);

      GtkWidget *menu = gtk_menu_new();
      GtkWidget *item = gtk_menu_item_new_with_label("Cancel Download");
      g_signal_connect(item, "activate",
                       G_CALLBACK(on_cancel_menu_item_clicked), download);
      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
      gtk_widget_show_all(menu);
      gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
      return TRUE;
    }
  }
  return FALSE;
}

void download_window_show(void) {
  if (!download_window) {
    download_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(download_window), "Downloads - Leaf Web");
    gtk_window_set_default_size(GTK_WINDOW(download_window), 800, 400);

    GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL);
    gtk_container_add(GTK_CONTAINER(download_window), scrolled);

    create_view_and_model();
    gtk_container_add(GTK_CONTAINER(scrolled), tree_view);

    g_signal_connect(tree_view, "row-activated", G_CALLBACK(on_row_activated),
                     NULL);
    g_signal_connect(tree_view, "button-press-event",
                     G_CALLBACK(on_button_press), NULL);

    g_signal_connect(download_window, "delete-event",
                     G_CALLBACK(gtk_widget_hide_on_delete), NULL);

    // Add a hint label
    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    // Re-parenting logic is messy, let's just rebuild the hierarchy properly
    // Destroy the scrolled window we just added to window
    gtk_widget_destroy(scrolled);

    // Proper layout
    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
    gtk_container_add(GTK_CONTAINER(download_window), vbox);

    GtkWidget *label =
        gtk_label_new("Double-click to Pause/Resume. Right-click to Cancel.");
    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);

    scrolled = gtk_scrolled_window_new(NULL, NULL);
    gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
    gtk_container_add(GTK_CONTAINER(scrolled), tree_view);
  }

  download_window_update();
  gtk_widget_show_all(download_window);
}

void download_window_hide(void) {
  if (download_window) {
    gtk_widget_hide(download_window);
  }
}

void download_window_update(void) {
  if (!download_store) {
    return;
  }

  gtk_list_store_clear(download_store);

  GList *downloads = download_manager_get_downloads();
  for (GList *iter = downloads; iter != NULL; iter = iter->next) {
    Download *download = (Download *)iter->data;

    char *speed_str = format_size(download->speed);
    char *speed_display = g_strdup_printf("%s/s", speed_str);
    char *eta_str = format_time(download->eta);
    char *multipart_str = g_strdup_printf("%d parts", download->num_parts);

    int progress = 0;
    if (download->total_size > 0) {
      progress =
          (int)((double)download->downloaded / download->total_size * 100.0);
    }

    const char *status_str = "Unknown";
    switch (download->state) {
    case DOWNLOAD_STATE_PENDING:
      status_str = "Pending";
      break;
    case DOWNLOAD_STATE_DOWNLOADING:
      status_str = "Downloading";
      break;
    case DOWNLOAD_STATE_PAUSED:
      status_str = "Paused";
      break;
    case DOWNLOAD_STATE_COMPLETED:
      status_str = "Completed";
      break;
    case DOWNLOAD_STATE_FAILED:
      status_str = "Failed";
      break;
    case DOWNLOAD_STATE_CANCELLED:
      status_str = "Cancelled";
      break;
    }

    GtkTreeIter tree_iter;
    gtk_list_store_append(download_store, &tree_iter);
    gtk_list_store_set(download_store, &tree_iter, COL_FILENAME,
                       download->filename, COL_PROGRESS, progress, COL_SPEED,
                       speed_display, COL_ETA, eta_str, COL_MULTIPART,
                       multipart_str, COL_STATUS, status_str, COL_DOWNLOAD_PTR,
                       download, -1);

    g_free(speed_str);
    g_free(speed_display);
    g_free(eta_str);
    g_free(multipart_str);
  }
  g_list_free(downloads);
}

// Auto-update downloads window periodically
static gboolean update_timer_callback(gpointer user_data) {
  if (download_window && gtk_widget_is_visible(download_window)) {
    download_window_update();
  }
  return G_SOURCE_CONTINUE;
}

__attribute__((constructor)) static void start_update_timer(void) {
  g_timeout_add(1000, update_timer_callback, NULL); // Update every second
}
