#include "ui.h"
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "mpris.h"
#include "plugin_manager.h"

/* Forward declarations */
static void on_playback_prev(GtkMenuItem *item, gpointer data);
static void on_playback_next(GtkMenuItem *item, gpointer data);
static void on_playback_seek_forward(GtkMenuItem *item, gpointer data);
static void on_playback_seek_backward(GtkMenuItem *item, gpointer data);
static void on_playback_frame_step(GtkMenuItem *item, gpointer data);
static void on_playback_goto_time(GtkMenuItem *item, gpointer data);
static void on_playback_speed(GtkMenuItem *item, gpointer data);
static void on_playback_ab_loop_a(GtkMenuItem *item, gpointer data);
static void on_playback_ab_loop_b(GtkMenuItem *item, gpointer data);
static void on_playback_ab_loop_clear(GtkMenuItem *item, gpointer data);
static void on_audio_track_selected(GtkMenuItem *item, gpointer data);
static void on_subtitle_track_selected(GtkMenuItem *item, gpointer data);
static void on_subtitle_load(GtkMenuItem *item, gpointer data);
static void on_subtitle_disable(GtkMenuItem *item, gpointer data);
static void update_chapter_menu(AppUI *ui);
static void on_chapter_selected(GtkMenuItem *item, gpointer data);
static void on_view_fullscreen(GtkMenuItem *item, gpointer data);
static void on_view_playlist(GtkMenuItem *item, gpointer data);
static void on_view_screenshot(GtkMenuItem *item, gpointer data);
static void on_open_scripts_folder(GtkMenuItem *item, gpointer data);

/* Property observation user data IDs */
enum {
    PROP_TIME_POS = 1,
    PROP_DURATION,
    PROP_PAUSE,
    PROP_VOLUME,
    PROP_MUTE,
    PROP_MEDIA_TITLE,
    PROP_PLAYLIST_POS,
    PROP_AB_LOOP_A,
    PROP_AB_LOOP_B,
    PROP_IDLE_ACTIVE,
    PROP_SHUFFLE,
    PROP_LOOP,
    PROP_CHAPTER,
};

struct AppUI {
    /* Main window */
    GtkWidget *window;
    
    /* Main vertical box */
    GtkWidget *main_vbox;
    
    /* Menu bar */
    GtkWidget *menubar;
    
    /* Paned container */
    GtkWidget *hpaned;
    
    /* Video container */
    GtkWidget *video_container;
    
    /* Video area */
    GtkWidget *video_area;
    
    /* Controls and playlist */
    Controls *controls;
    Playlist *playlist;
    
    /* Player */
    Player *player;
    
    /* Preferences */
    Preferences *prefs;
    
    /* State */
    gboolean is_fullscreen;
    gboolean playlist_visible;
    gboolean always_on_top;
    
    /* Fullscreen controls overlay */
    GtkWidget *fs_window;
    
    /* Menus for dynamic updates */
    GtkWidget *audio_menu;
    GtkWidget *subtitle_menu;
    GtkWidget *speed_menu;
    GtkWidget *aspect_menu;
    GtkWidget *chapter_menu;
    GtkWidget *recent_menu;
    GtkWidget *mute_item;
    
    GtkRecentManager *recent_manager;
    
    /* Auto-hide controls in fullscreen */
    guint auto_hide_timer_id;
    
    /* MPRIS state tracking */
    double last_mpris_pos;
    
    /* Plugin manager */
    PluginManager *plugin_manager;
};

/* Forward declarations */
static void create_menubar(AppUI *ui);
static void on_video_area_realize(GtkWidget *widget, gpointer data);
static void on_player_event(Player *player, mpv_event *event, gpointer user_data);
static void on_fullscreen_requested(gboolean fullscreen, gpointer user_data);
static gboolean on_window_configure(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
static gboolean on_window_delete(GtkWidget *widget, GdkEvent *event, gpointer data);
static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data);
static void on_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
                                  GtkSelectionData *selection, guint info, guint time, gpointer data);
static gboolean on_video_area_scroll(GtkWidget *widget, GdkEventScroll *event, gpointer data);
static gboolean on_video_area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data);
static gboolean on_video_area_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data);
static gboolean auto_hide_timer_cb(gpointer data);
static void add_path_to_playlist(AppUI *ui, const char *path, gboolean clear);
static void on_recent_item_activated(GtkRecentChooser *chooser, gpointer data);
static void on_controls_play_pause(gpointer data);

/* Menu callbacks */
static void on_file_open(GtkMenuItem *item, gpointer data);
static void on_file_open_directory(GtkMenuItem *item, gpointer data);
static void on_file_open_url(GtkMenuItem *item, gpointer data);
static void on_file_save_playlist(GtkMenuItem *item, gpointer data);
static void on_file_quit(GtkMenuItem *item, gpointer data);
static void on_playback_play_pause(GtkMenuItem *item, gpointer data);
static void on_playback_stop(GtkMenuItem *item, gpointer data);
static void on_playback_seek_forward(GtkMenuItem *item, gpointer data);
static void on_playback_seek_backward(GtkMenuItem *item, gpointer data);
static void on_playback_frame_step(GtkMenuItem *item, gpointer data);
static void on_playback_goto_time(GtkMenuItem *item, gpointer data);
static void on_playback_speed(GtkMenuItem *item, gpointer data);
static void on_playback_ab_loop_a(GtkMenuItem *item, gpointer data);
static void on_playback_ab_loop_b(GtkMenuItem *item, gpointer data);
static void on_playback_ab_loop_clear(GtkMenuItem *item, gpointer data);
static void on_audio_track_selected(GtkMenuItem *item, gpointer data);
static void on_subtitle_track_selected(GtkMenuItem *item, gpointer data);
static void on_subtitle_load(GtkMenuItem *item, gpointer data);
static void on_subtitle_disable(GtkMenuItem *item, gpointer data);
static void on_view_fullscreen(GtkMenuItem *item, gpointer data);
static void on_view_playlist(GtkMenuItem *item, gpointer data);
static void on_view_always_on_top(GtkMenuItem *item, gpointer data);
static void on_view_screenshot(GtkMenuItem *item, gpointer data);
static void on_view_preferences(GtkMenuItem *item, gpointer data);
static void on_aspect_ratio_selected(GtkMenuItem *item, gpointer data);
static void on_audio_mute(GtkMenuItem *item, gpointer data);
static void on_help_about(GtkMenuItem *item, gpointer data);

/* Plugin API wrapper forward declarations */
static AppUI *g_current_ui;
static void plugin_api_play(void);
static void plugin_api_pause(void);
static void plugin_api_stop(void);
static void plugin_api_toggle_pause(void);
static void plugin_api_seek(double seconds);
static void plugin_api_seek_absolute(double position);
static double plugin_api_get_position(void);
static double plugin_api_get_duration(void);
static double plugin_api_get_volume(void);
static gboolean plugin_api_is_paused(void);
static gboolean plugin_api_is_playing(void);
static char* plugin_api_get_current_file(void);
static char* plugin_api_get_media_title(void);
static void plugin_api_take_screenshot(void);
static void plugin_api_take_screenshot_to_file(const char *path);

AppUI* ui_new(void)
{
    AppUI *ui = g_new0(AppUI, 1);
    
    /* Create player */
    ui->player = player_new();
    if (!ui->player) {
        g_free(ui);
        return NULL;
    }
    
    /* Load preferences */
    ui->prefs = preferences_new();
    preferences_load(ui->prefs);
    
    /* Main window */
    ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(ui->window), "Kino");
    gtk_window_set_default_size(GTK_WINDOW(ui->window), 900, 600);
    gtk_window_set_position(GTK_WINDOW(ui->window), GTK_WIN_POS_CENTER);
    
    /* Set default application icon for all windows (appears in title bar and taskbar) */
    if (!gtk_window_set_default_icon_from_file("icon.png", NULL)) {
        if (!gtk_window_set_default_icon_from_file("assets/icon.png", NULL)) {
            gtk_window_set_default_icon_from_file("/usr/local/lib/gtk2-mpv-player/icon.png", NULL);
        }
    }
    
    g_signal_connect(ui->window, "delete-event", G_CALLBACK(on_window_delete), ui);
    g_signal_connect(ui->window, "configure-event", G_CALLBACK(on_window_configure), ui);
    g_signal_connect(ui->window, "key-press-event", G_CALLBACK(on_key_press), ui);
    
    /* Main vertical box */
    ui->main_vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(ui->window), ui->main_vbox);
    
    /* Initialize plugin manager (must be before create_menubar) */
    ui->plugin_manager = plugin_manager_new(ui);

    /* Set up plugin API callbacks and load plugins BEFORE creating menu */
    g_current_ui = ui;
    plugin_manager_set_player_callbacks(ui->plugin_manager,
        plugin_api_play,
        plugin_api_pause,
        plugin_api_stop,
        plugin_api_toggle_pause,
        plugin_api_seek,
        plugin_api_seek_absolute,
        plugin_api_get_position,
        plugin_api_get_duration,
        plugin_api_get_volume,
        plugin_api_is_paused,
        plugin_api_is_playing,
        plugin_api_get_current_file,
        plugin_api_get_media_title,
        plugin_api_take_screenshot,
        plugin_api_take_screenshot_to_file
    );
    plugin_manager_load_all(ui->plugin_manager);
    
    /* Menu bar */
    create_menubar(ui);
    gtk_box_pack_start(GTK_BOX(ui->main_vbox), ui->menubar, FALSE, FALSE, 0);
    
    /* Horizontal paned for video + playlist */
    ui->hpaned = gtk_hpaned_new();
    gtk_box_pack_start(GTK_BOX(ui->main_vbox), ui->hpaned, TRUE, TRUE, 0);
    
    /* Container for video to help with black bars/background */
    ui->video_container = gtk_event_box_new();
    GdkColor black = {0, 0, 0, 0};
    gtk_widget_modify_bg(ui->video_container, GTK_STATE_NORMAL, &black);
    gtk_paned_pack1(GTK_PANED(ui->hpaned), ui->video_container, TRUE, TRUE);
    
    ui->video_area = gtk_drawing_area_new();
    gtk_widget_set_size_request(ui->video_area, 640, 360);
    gtk_container_add(GTK_CONTAINER(ui->video_container), ui->video_area);
    
    gtk_widget_add_events(ui->video_container, GDK_BUTTON_PRESS_MASK | GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK);
    g_signal_connect(ui->video_area, "realize", G_CALLBACK(on_video_area_realize), ui);
    g_signal_connect(ui->video_container, "scroll-event", G_CALLBACK(on_video_area_scroll), ui);
    g_signal_connect(ui->video_container, "button-press-event", G_CALLBACK(on_video_area_button_press), ui);
    g_signal_connect(ui->video_container, "motion-notify-event", G_CALLBACK(on_video_area_motion), ui);
    
    /* Enable drag and drop on container as well */
    static GtkTargetEntry target_entries[] = {
        {"text/uri-list", 0, 0}
    };
    gtk_drag_dest_set(ui->video_container, GTK_DEST_DEFAULT_ALL, 
                      target_entries, 1, GDK_ACTION_COPY);
    g_signal_connect(ui->video_container, "drag-data-received", G_CALLBACK(on_drag_data_received), ui);
    
    /* Playlist */
    ui->playlist = playlist_new(ui->player);
    GtkWidget *playlist_widget = playlist_get_widget(ui->playlist);
    gtk_widget_set_size_request(playlist_widget, 250, -1);
    gtk_paned_pack2(GTK_PANED(ui->hpaned), playlist_widget, FALSE, TRUE);
    
    /* Handle visibility manually */
    gtk_widget_set_no_show_all(playlist_widget, TRUE);
    
    ui->playlist_visible = ui->prefs->show_playlist;
    if (ui->playlist_visible) {
        gtk_widget_show(playlist_widget);
    }
    
    /* Controls */
    ui->controls = controls_new(ui->player, ui->prefs);
    controls_set_fullscreen_callback(ui->controls, on_fullscreen_requested, ui);
    controls_set_play_pause_callback(ui->controls, on_controls_play_pause, ui);
    gtk_box_pack_start(GTK_BOX(ui->main_vbox), controls_get_widget(ui->controls), FALSE, FALSE, 0);
    
    /* Set player event callback */
    player_set_event_callback(ui->player, on_player_event, ui);
    
    /* Set mpv config path */
    if (ui->prefs->mpv_config_path) {
        player_set_config_path(ui->player, ui->prefs->mpv_config_path);
    }
    
    /* Set default volume */
    player_set_volume(ui->player, ui->prefs->default_volume);
    
    /* Set initial OSD and focus settings */
    player_set_option_string(ui->player, "osd-level", ui->prefs->enable_osd ? "1" : "0");
    player_set_option_string(ui->player, "osd-bar", ui->prefs->enable_osd ? "yes" : "no");
    
    if (ui->prefs->hide_focus_rect) {
        gtk_rc_parse_string("style \"no-focus-rect\" { GtkWidget::focus-line-width = 0 GtkWidget::focus-padding = 0 } widget \"*\" style \"no-focus-rect\"");
    }
    
    /* Observe chapter changes */
    player_observe_property(ui->player, "chapter", MPV_FORMAT_INT64, PROP_CHAPTER);
    
    ui->is_fullscreen = FALSE;
    ui->always_on_top = FALSE;
    ui->auto_hide_timer_id = 0;
    
    /* Show window */
    gtk_widget_show_all(ui->window);
    
    /* Since we used set_no_show_all on playlist, it remains hidden if it was hidden. 
       If prefs say show, we already called show() above. */
    
    if (ui->always_on_top) {
        gtk_window_set_keep_above(GTK_WINDOW(ui->window), TRUE);
    }
    
    /* Recent files */
    ui->recent_manager = gtk_recent_manager_get_default();
    
    if (ui->prefs->use_mpris) {
        mpris_init(ui);
    }
    
    return ui;
}

void ui_destroy(AppUI *ui)
{
    if (!ui) return;
    
    if (ui->auto_hide_timer_id > 0) {
        g_source_remove(ui->auto_hide_timer_id);
    }
    
    mpris_destroy(ui);
    
    /* Destroy plugin manager */
    plugin_manager_destroy(ui->plugin_manager);
    
    if (ui->fs_window) {
        gtk_widget_destroy(ui->fs_window);
    }
    
    preferences_free(ui->prefs);
    controls_destroy(ui->controls);
    playlist_destroy(ui->playlist);
    player_destroy(ui->player);
    g_free(ui);
}

void ui_set_preferences(AppUI *ui, Preferences *prefs)
{
    if (!ui || !prefs) return;
    
    if (ui->prefs) {
        preferences_free(ui->prefs);
    }
    
    ui->prefs = prefs;
    
    /* Apply some immediate settings */
    if (ui->player) {
        player_set_volume_boost(ui->player, ui->prefs->enable_volume_boost);
        player_set_volume(ui->player, ui->prefs->default_volume);
        
        if (ui->prefs->screenshot_directory) {
            player_set_option_string(ui->player, "screenshot-directory", ui->prefs->screenshot_directory);
        }
    }
    
    if (ui->controls) {
        controls_update_volume_boost(ui->controls, ui->prefs->enable_volume_boost);
    }
    
    /* Update playlist visibility if UI is already realized */
    if (ui->playlist) {
        GtkWidget *playlist_widget = playlist_get_widget(ui->playlist);
        if (ui->prefs->show_playlist) {
            gtk_widget_show(playlist_widget);
        } else {
            gtk_widget_hide(playlist_widget);
        }
    }
}

GtkWidget* ui_get_window(AppUI *ui)
{
    if (!ui) return NULL;
    return ui->window;
}

Player* ui_get_player(AppUI *ui)
{
    if (!ui) return NULL;
    return ui->player;
}

Playlist* ui_get_playlist(AppUI *ui)
{
    if (!ui) return NULL;
    return ui->playlist;
}

PluginManager* ui_get_plugin_manager(AppUI *ui)
{
    if (!ui) return NULL;
    return ui->plugin_manager;
}

/* Static wrapper functions for plugin API */

static void plugin_api_play(void) {
    if (g_current_ui && g_current_ui->player) player_play(g_current_ui->player);
}

static void plugin_api_pause(void) {
    if (g_current_ui && g_current_ui->player) player_pause(g_current_ui->player);
}

static void plugin_api_stop(void) {
    if (g_current_ui && g_current_ui->player) player_stop(g_current_ui->player);
}

static void plugin_api_toggle_pause(void) {
    if (g_current_ui && g_current_ui->player) player_toggle_pause(g_current_ui->player);
}

static void plugin_api_seek(double seconds) {
    if (g_current_ui && g_current_ui->player) player_seek(g_current_ui->player, seconds);
}

static void plugin_api_seek_absolute(double position) {
    if (g_current_ui && g_current_ui->player) player_seek_absolute(g_current_ui->player, position);
}

static double plugin_api_get_position(void) {
    if (g_current_ui && g_current_ui->player) return player_get_position(g_current_ui->player);
    return 0.0;
}

static double plugin_api_get_duration(void) {
    if (g_current_ui && g_current_ui->player) return player_get_duration(g_current_ui->player);
    return 0.0;
}

static double plugin_api_get_volume(void) {
    if (g_current_ui && g_current_ui->player) return player_get_volume(g_current_ui->player);
    return 100.0;
}

static gboolean plugin_api_is_paused(void) {
    if (g_current_ui && g_current_ui->player) return player_get_paused(g_current_ui->player);
    return TRUE;
}

static gboolean plugin_api_is_playing(void) {
    if (g_current_ui && g_current_ui->player) return !player_get_paused(g_current_ui->player) && !player_is_idle(g_current_ui->player);
    return FALSE;
}

static char* plugin_api_get_current_file(void) {
    if (g_current_ui && g_current_ui->player) return player_get_filename(g_current_ui->player);
    return NULL;
}

static char* plugin_api_get_media_title(void) {
    if (g_current_ui && g_current_ui->player) return player_get_media_title(g_current_ui->player);
    return NULL;
}

static void plugin_api_take_screenshot(void) {
    if (g_current_ui && g_current_ui->player) player_screenshot(g_current_ui->player);
}

static void plugin_api_take_screenshot_to_file(const char *path) {
    if (g_current_ui && g_current_ui->player) player_screenshot_to_file(g_current_ui->player, path);
}

void ui_run(AppUI *ui)
{
    (void)ui;
    gtk_main();
}

void ui_open_file(AppUI *ui)
{
    if (!ui) return;
    
    GSList *files = dialogs_open_files(GTK_WINDOW(ui->window), ui->prefs);
    if (files) {
        playlist_clear(ui->playlist);
        gboolean first = TRUE;
        for (GSList *iter = files; iter != NULL; iter = iter->next) {
            playlist_add_file(ui->playlist, (const char *)iter->data, !first);
            first = FALSE;
        }
        
        if (playlist_get_count(ui->playlist) > 0) {
            playlist_play_index(ui->playlist, 0);
        }
        g_slist_free_full(files, g_free);
    }
}

static gboolean is_media_file(const char *filename)
{
    const char *exts[] = {
        ".mkv", ".mp4", ".avi", ".wmv", ".mov", ".webm", ".flv", ".m4v", ".ts", ".m2ts", 
        ".vob", ".ogv", ".3gp", ".mp3", ".flac", ".ogg", ".wav", ".m4a", ".aac", ".opus", 
        NULL
    };
    
    char *lower = g_utf8_strdown(filename, -1);
    gboolean found = FALSE;
    
    for (int i = 0; exts[i] != NULL; i++) {
        if (g_str_has_suffix(lower, exts[i])) {
            found = TRUE;
            break;
        }
    }
    
    g_free(lower);
    return found;
}

void ui_open_directory(AppUI *ui)
{
    if (!ui) return;
    
    char *dir_path = dialogs_open_directory(GTK_WINDOW(ui->window), ui->prefs);
    if (dir_path) {
        add_path_to_playlist(ui, dir_path, TRUE);
        if (playlist_get_count(ui->playlist) > 0) {
            playlist_play_index(ui->playlist, 0);
        }
        g_free(dir_path);
    }
}

void ui_open_url(AppUI *ui)
{
    if (!ui) return;
    
    char *url = dialogs_open_url(GTK_WINDOW(ui->window), ui->prefs);
    if (url) {
        playlist_add_file(ui->playlist, url, TRUE);
        g_free(url);
    }
}

void ui_load_subtitle(AppUI *ui)
{
    if (!ui) return;
    
    char *subtitle = dialogs_open_subtitle(GTK_WINDOW(ui->window), ui->prefs);
    if (subtitle) {
        player_load_subtitle(ui->player, subtitle);
        g_free(subtitle);
    }
}

void ui_toggle_fullscreen(AppUI *ui)
{
    if (!ui) return;
    
    ui->is_fullscreen = !ui->is_fullscreen;
    GtkWidget *controls_widget = controls_get_widget(ui->controls);
    
    if (ui->is_fullscreen) {
        gtk_widget_hide(ui->menubar);
        if (ui->playlist_visible) {
            gtk_widget_hide(playlist_get_widget(ui->playlist));
        }
        
        /* Create overlay window for controls */
        ui->fs_window = gtk_window_new(GTK_WINDOW_POPUP);
        gtk_window_set_type_hint(GTK_WINDOW(ui->fs_window), GDK_WINDOW_TYPE_HINT_DOCK);
        
        /* Move controls to overlay */
        g_object_ref(controls_widget);
        gtk_container_remove(GTK_CONTAINER(ui->main_vbox), controls_widget);
        gtk_container_add(GTK_CONTAINER(ui->fs_window), controls_widget);
        g_object_unref(controls_widget);
        
        /* Position at bottom of screen */
        GtkRequisition req;
        gtk_widget_size_request(controls_widget, &req);
        int ctrl_h = req.height;
        
        /* For fullscreen, we should use the specific monitor size */
        GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(ui->window));
        gint monitor_num = gdk_screen_get_monitor_at_window(screen, ui->window->window);
        GdkRectangle geom;
        gdk_screen_get_monitor_geometry(screen, monitor_num, &geom);
        
        gtk_window_set_default_size(GTK_WINDOW(ui->fs_window), geom.width, ctrl_h);
        gtk_window_move(GTK_WINDOW(ui->fs_window), geom.x, geom.y + geom.height - ctrl_h);
        
        gtk_widget_show_all(ui->fs_window);
        gtk_window_fullscreen(GTK_WINDOW(ui->window));
        
        /* Start auto-hide timer */
        if (ui->auto_hide_timer_id > 0) {
            g_source_remove(ui->auto_hide_timer_id);
        }
        ui->auto_hide_timer_id = g_timeout_add(3000, auto_hide_timer_cb, ui);
    } else {
        gtk_window_unfullscreen(GTK_WINDOW(ui->window));
        
        /* Restore controls to main window */
        if (ui->fs_window) {
            gtk_widget_hide(ui->fs_window);
            g_object_ref(controls_widget);
            gtk_container_remove(GTK_CONTAINER(ui->fs_window), controls_widget);
            gtk_box_pack_start(GTK_BOX(ui->main_vbox), controls_widget, FALSE, FALSE, 0);
            g_object_unref(controls_widget);
            
            gtk_widget_destroy(ui->fs_window);
            ui->fs_window = NULL;
        }
        
        gtk_widget_show(ui->menubar);
        gtk_widget_show(controls_widget);
        if (ui->playlist_visible) {
            gtk_widget_show(playlist_get_widget(ui->playlist));
        }
        
        /* Stop auto-hide timer unless windowed hiding is on */
        if (!ui->prefs->hide_cursor_windowed && ui->auto_hide_timer_id > 0) {
            g_source_remove(ui->auto_hide_timer_id);
            ui->auto_hide_timer_id = 0;
            /* Restore cursor */
            GdkWindow *window = gtk_widget_get_window(ui->video_area);
            if (window) gdk_window_set_cursor(window, NULL);
        }
    }
}



void ui_toggle_playlist(AppUI *ui)
{
    if (!ui) return;
    
    ui->playlist_visible = !ui->playlist_visible;
    
    GtkWidget *playlist_widget = playlist_get_widget(ui->playlist);
    if (ui->playlist_visible) {
        gtk_widget_show(playlist_widget);
    } else {
        gtk_widget_hide(playlist_widget);
    }
}

void ui_toggle_always_on_top(AppUI *ui)
{
    if (!ui) return;
    
    ui->always_on_top = !ui->always_on_top;
    gtk_window_set_keep_above(GTK_WINDOW(ui->window), ui->always_on_top);
}

void ui_update_title(AppUI *ui, const char *media_title)
{
    if (!ui) return;
    
    char title[1024];
    if (media_title && strlen(media_title) > 0) {
        snprintf(title, sizeof(title), "%s - Kino", media_title);
    } else {
        snprintf(title, sizeof(title), "Kino");
    }
    
    gtk_window_set_title(GTK_WINDOW(ui->window), title);
}

/* Private functions */

static void on_video_area_realize(GtkWidget *widget, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    
    /* Get XID of the video area */
    GdkWindow *gdk_window = gtk_widget_get_window(widget);
    unsigned long xid = GDK_WINDOW_XID(gdk_window);
    
    /* Set window and initialize player */
    player_set_window(ui->player, xid);
    
    if (player_init(ui->player) < 0) {
        fprintf(stderr, "Failed to initialize player\n");
        return;
    }
    
    /* Set options */
    player_set_option_string(ui->player, "osd-level", "1");
    if (ui->prefs->remember_position) {
        player_set_option_string(ui->player, "save-position-on-quit", "yes");
    }
    
    /* Observe properties for UI updates */
    player_observe_property(ui->player, "time-pos", MPV_FORMAT_DOUBLE, PROP_TIME_POS);
    player_observe_property(ui->player, "duration", MPV_FORMAT_DOUBLE, PROP_DURATION);
    player_observe_property(ui->player, "pause", MPV_FORMAT_FLAG, PROP_PAUSE);
    player_observe_property(ui->player, "volume", MPV_FORMAT_DOUBLE, PROP_VOLUME);
    player_observe_property(ui->player, "mute", MPV_FORMAT_FLAG, PROP_MUTE);
    player_observe_property(ui->player, "media-title", MPV_FORMAT_STRING, PROP_MEDIA_TITLE);
    player_observe_property(ui->player, "playlist-pos", MPV_FORMAT_INT64, PROP_PLAYLIST_POS);
    player_observe_property(ui->player, "idle-active", MPV_FORMAT_FLAG, PROP_IDLE_ACTIVE);
    player_observe_property(ui->player, "shuffle", MPV_FORMAT_FLAG, PROP_SHUFFLE);
    player_observe_property(ui->player, "loop-playlist", MPV_FORMAT_STRING, PROP_LOOP);
}

static void on_player_event(Player *player, mpv_event *event, gpointer user_data)
{
    (void)player;
    AppUI *ui = (AppUI *)user_data;
    
    switch (event->event_id) {
        case MPV_EVENT_PROPERTY_CHANGE: {
            mpv_event_property *prop = (mpv_event_property *)event->data;
            
            if (prop->data == NULL) break;
            
            switch (event->reply_userdata) {
                case PROP_TIME_POS:
                    if (prop->format == MPV_FORMAT_DOUBLE) {
                        double pos = *(double *)prop->data;
                        controls_update_position(ui->controls, pos);
                        
                        /* Detect seeking and notify MPRIS */
                        if (fabs(pos - ui->last_mpris_pos) > 2.0) {
                            mpris_emit_seeked(ui, (gint64)(pos * 1000000.0));
                        }
                        ui->last_mpris_pos = pos;
                    }
                    break;
                    
                case PROP_DURATION:
                    if (prop->format == MPV_FORMAT_DOUBLE) {
                        double dur = *(double *)prop->data;
                        controls_update_duration(ui->controls, dur);
                    }
                    break;
                    
                case PROP_PAUSE:
                    if (prop->format == MPV_FORMAT_FLAG) {
                        int paused = *(int *)prop->data;
                        controls_update_pause_state(ui->controls, paused);
                        mpris_update_playback_status(ui);
                    }
                    break;
                    
                case PROP_VOLUME:
                    if (prop->format == MPV_FORMAT_DOUBLE) {
                        double vol = *(double *)prop->data;
                        controls_update_volume(ui->controls, vol);
                        mpris_update_volume(ui);
                    }
                    break;
                    
                case PROP_MUTE:
                    if (prop->format == MPV_FORMAT_FLAG) {
                        int muted = *(int *)prop->data;
                        controls_update_mute_state(ui->controls, muted);
                        if (ui->mute_item) {
                            g_signal_handlers_block_by_func(ui->mute_item, G_CALLBACK(on_audio_mute), ui);
                            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui->mute_item), muted);
                            g_signal_handlers_unblock_by_func(ui->mute_item, G_CALLBACK(on_audio_mute), ui);
                        }
                    }
                    break;
                    
                case PROP_MEDIA_TITLE:
                    if (prop->format == MPV_FORMAT_STRING) {
                        char *title = *(char **)prop->data;
                        ui_update_title(ui, title);
                        mpris_update_metadata(ui);
                    }
                    break;
                    
                case PROP_PLAYLIST_POS:
                    if (prop->format == MPV_FORMAT_INT64) {
                        int64_t pos = *(int64_t *)prop->data;
                        playlist_set_current_index(ui->playlist, (int)pos);
                    }
                    break;
                    
                case PROP_IDLE_ACTIVE:
                    if (prop->format == MPV_FORMAT_FLAG) {
                        int idle = *(int *)prop->data;
                        if (idle) {
                            controls_reset(ui->controls);
                            ui_update_title(ui, "Kino");
                        }
                        mpris_update_playback_status(ui);
                    }
                    break;
                    
                case PROP_SHUFFLE:
                    mpris_update_loop_shuffle(ui);
                    break;
                    
                case PROP_LOOP:
                    mpris_update_loop_shuffle(ui);
                    break;
                
                case PROP_CHAPTER:
                    /* Just refresh the menu to update radio selection */
                    update_chapter_menu(ui);
                    break;
            }
            break;
        }
        
        case MPV_EVENT_START_FILE:
            ui->last_mpris_pos = 0;
            mpris_update_playback_status(ui);
            break;
            
        case MPV_EVENT_FILE_LOADED: {
            /* Sync playlist position */
            playlist_sync_from_player(ui->playlist);
            
            /* Update Play/Pause icon (loading starts playing) */
            controls_update_pause_state(ui->controls, FALSE);
            
            /* Update audio/subtitle menus */
            void update_track_menus(AppUI *ui);
            update_track_menus(ui);
            update_chapter_menu(ui);
            
            mpris_update_metadata(ui);
            mpris_update_playback_status(ui);
            
            /* Auto-resize window to fit video */
            if (ui->prefs->auto_resize && !ui->is_fullscreen) {
                int vw, vh;
                player_get_video_resolution(ui->player, &vw, &vh);
                if (vw > 0 && vh > 0) {
                    GtkAllocation menu_alloc = {0}, ctrl_alloc = {0}, playlist_alloc = {0};
                    gtk_widget_get_allocation(ui->menubar, &menu_alloc);
                    gtk_widget_get_allocation(controls_get_widget(ui->controls), &ctrl_alloc);
                    
                    int win_w = vw;
                    int win_h = vh + menu_alloc.height + ctrl_alloc.height;
                    
                    if (ui->playlist_visible) {
                        gtk_widget_get_allocation(playlist_get_widget(ui->playlist), &playlist_alloc);
                        win_w += playlist_alloc.width;
                    }
                    
                    /* Don't resize if it would be larger than the screen (simplified check) */
                    GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(ui->window));
                    if (win_w < gdk_screen_get_width(screen) && win_h < gdk_screen_get_height(screen)) {
                        gtk_window_resize(GTK_WINDOW(ui->window), win_w, win_h);
                    }
                }
            }
            
            /* Add to recent files */
            char *filename = player_get_filename(ui->player);
            if (filename) {
                char *uri = NULL;
                if (g_str_has_prefix(filename, "/")) {
                    uri = g_filename_to_uri(filename, NULL, NULL);
                } else if (strstr(filename, "://")) {
                    uri = g_strdup(filename);
                }
                
                if (uri) {
                    GtkRecentData data;
                    memset(&data, 0, sizeof(data));
                    data.display_name = player_get_media_title(ui->player);
                    data.mime_type = "video/mp4"; /* Generic */
                    data.app_name = "gtk2-mpv-player";
                    data.app_exec = "gtk2-mpv-player %u";
                    
                    gtk_recent_manager_add_full(ui->recent_manager, uri, &data);
                    g_free(data.display_name);
                    g_free(uri);
                }
                g_free(filename);
            }
            
            /* Start auto-hide timer if needed */
            if (ui->is_fullscreen || ui->prefs->hide_cursor_windowed) {
                if (ui->auto_hide_timer_id > 0) g_source_remove(ui->auto_hide_timer_id);
                ui->auto_hide_timer_id = g_timeout_add(3000, auto_hide_timer_cb, ui);
            }
            break;
        }
        
        case MPV_EVENT_END_FILE:
            /* mpv now handles looping natively via loop-playlist property */
            break;
            
        case MPV_EVENT_SHUTDOWN:
            gtk_main_quit();
            break;
            
        default:
            break;
    }
}

static void on_fullscreen_requested(gboolean fullscreen, gpointer user_data)
{
    (void)fullscreen;
    AppUI *ui = (AppUI *)user_data;
    ui_toggle_fullscreen(ui);
}

static gboolean on_window_configure(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
{
    (void)event;
    AppUI *ui = (AppUI *)data;
    
    /* Force full redraw of main areas on resize to prevent artifacts */
    gtk_widget_queue_draw(ui->window);
    gtk_widget_queue_draw(ui->video_area);
    
    return FALSE; /* Propagate event */
}

static gboolean on_window_delete(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    (void)widget;
    (void)event;
    (void)data;
    
    gtk_main_quit();
    return FALSE;
}

static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
    (void)widget;
    AppUI *ui = (AppUI *)data;
    
    switch (event->keyval) {
        case GDK_Escape:
            if (ui->is_fullscreen) {
                ui_toggle_fullscreen(ui);
            }
            return TRUE;
            
        case GDK_F11:
        case GDK_f:
            ui_toggle_fullscreen(ui);
            return TRUE;
            
        case GDK_space:
            on_playback_play_pause(NULL, ui);
            return TRUE;
            
        case GDK_Page_Up:
            player_prev_chapter(ui->player);
            return TRUE;
            
        case GDK_Page_Down:
            player_next_chapter(ui->player);
            return TRUE;
            
        case GDK_Left:
            player_seek(ui->player, -5);
            return TRUE;
            
        case GDK_Right:
            player_seek(ui->player, 5);
            return TRUE;
            
        case GDK_Up:
            player_set_volume(ui->player, player_get_volume(ui->player) + 5);
            return TRUE;
            
        case GDK_Down:
            player_set_volume(ui->player, player_get_volume(ui->player) - 5);
            return TRUE;
            
        case GDK_m:
            player_set_muted(ui->player, !player_get_muted(ui->player));
            return TRUE;
            
        default:
            break;
    }
    
    return FALSE;
}

static gboolean on_drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
                             guint time, gpointer data)
{
    (void)widget;
    (void)x;
    (void)y;
    (void)data;
    
    GdkAtom target = gtk_drag_dest_find_target(widget, context, NULL);
    if (target != GDK_NONE) {
        gtk_drag_get_data(widget, context, target, time);
        return TRUE;
    }
    return FALSE;
}

static void on_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
                                  GtkSelectionData *selection, guint info, guint time, gpointer data)
{
    (void)widget;
    (void)x;
    (void)y;
    (void)info;
    
    AppUI *ui = (AppUI *)data;
    
    if (gtk_selection_data_get_length(selection) > 0) {
        char **uris = gtk_selection_data_get_uris(selection);
        if (uris) {
            for (int i = 0; uris[i] != NULL; i++) {
                char *filename = g_filename_from_uri(uris[i], NULL, NULL);
                if (filename) {
                    add_path_to_playlist(ui, filename, FALSE);
                    g_free(filename);
                }
            }
            g_strfreev(uris);
        }
    }
    
    gtk_drag_finish(context, TRUE, FALSE, time);
}

static gboolean on_video_area_scroll(GtkWidget *widget, GdkEventScroll *event, gpointer data)
{
    (void)widget;
    AppUI *ui = (AppUI *)data;
    double vol = player_get_volume(ui->player);
    
    if (event->direction == GDK_SCROLL_UP) {
        player_set_volume(ui->player, vol + 5);
    } else if (event->direction == GDK_SCROLL_DOWN) {
        player_set_volume(ui->player, vol - 5);
    }
    
    return TRUE;
}

static gboolean on_video_area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    (void)widget;
    AppUI *ui = (AppUI *)data;
    
    if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
        ui_toggle_fullscreen(ui);
        return TRUE;
    } else if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
        on_playback_play_pause(NULL, ui);
        return TRUE;
    }
    
    return FALSE;
}

static gboolean auto_hide_timer_cb(gpointer data)
{
    AppUI *ui = (AppUI *)data;
    
    /* Hide controls only if in fullscreen */
    if (ui->is_fullscreen) {
        if (ui->fs_window) {
            gtk_widget_hide(ui->fs_window);
        } else {
            gtk_widget_hide(controls_get_widget(ui->controls));
        }
    }
    
    /* Hide cursor if in fullscreen OR if hide_cursor_windowed is enabled */
    if (ui->is_fullscreen || ui->prefs->hide_cursor_windowed) {
        GdkWindow *window = gtk_widget_get_window(ui->video_area);
        if (window) {
            GdkCursor *cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
            gdk_window_set_cursor(window, cursor);
            gdk_cursor_unref(cursor);
        }
    }
    
    ui->auto_hide_timer_id = 0;
    return FALSE; /* Stop timer */
}

static gboolean on_video_area_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
    (void)widget;
    (void)event;
    AppUI *ui = (AppUI *)data;
    
    if (ui->is_fullscreen || ui->prefs->hide_cursor_windowed) {
        /* Show controls */
        if (ui->is_fullscreen && ui->fs_window) {
            gtk_widget_show_all(ui->fs_window);
        } else {
            gtk_widget_show(controls_get_widget(ui->controls));
        }
        
        /* Show cursor */
        GdkWindow *window = gtk_widget_get_window(ui->video_area);
        if (window) {
            gdk_window_set_cursor(window, NULL); /* Restore default cursor */
        }
        
        /* Reset timer */
        if (ui->auto_hide_timer_id > 0) {
            g_source_remove(ui->auto_hide_timer_id);
        }
        ui->auto_hide_timer_id = g_timeout_add(3000, auto_hide_timer_cb, ui);
    }
    
    return FALSE;
}


static void add_path_to_playlist(AppUI *ui, const char *path, gboolean clear)
{
    if (!ui || !path) return;
    
    if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
        GDir *dir = g_dir_open(path, 0, NULL);
        if (dir) {
            const char *name;
            GSList *file_list = NULL;
            while ((name = g_dir_read_name(dir)) != NULL) {
                if (is_media_file(name)) {
                    file_list = g_slist_prepend(file_list, g_strdup(name));
                }
            }
            g_dir_close(dir);
            
            if (file_list) {
                if (clear) playlist_clear(ui->playlist);
                file_list = g_slist_sort(file_list, (GCompareFunc)g_ascii_strcasecmp);
                gboolean first = clear;
                for (GSList *iter = file_list; iter != NULL; iter = iter->next) {
                    char *full_path = g_build_filename(path, (char *)iter->data, NULL);
                    playlist_add_file(ui->playlist, full_path, !first);
                    first = FALSE;
                    g_free(full_path);
                }
                g_slist_free_full(file_list, g_free);
            }
        }
    } else {
        if (clear) playlist_clear(ui->playlist);
        playlist_add_file(ui->playlist, path, !clear);
    }
}

/* Menu population helpers */

static void clear_menu(GtkWidget *menu)
{
    GList *children = gtk_container_get_children(GTK_CONTAINER(menu));
    GList *iter;
    for (iter = children; iter != NULL; iter = iter->next) {
        gtk_widget_destroy(GTK_WIDGET(iter->data));
    }
    g_list_free(children);
}

void update_track_menus(AppUI *ui)
{
    if (!ui || !ui->player) return;
    
    /* Update Audio Menu */
    clear_menu(ui->audio_menu);
    int audio_count = 0;
    char **audio_tracks = player_get_audio_track_list(ui->player, &audio_count);
    
    if (audio_count == 0) {
        GtkWidget *item = gtk_menu_item_new_with_label("None available");
        gtk_widget_set_sensitive(item, FALSE);
        gtk_menu_shell_append(GTK_MENU_SHELL(ui->audio_menu), item);
    } else {
        for (int i = 0; i < audio_count; i++) {
            GtkWidget *item = gtk_menu_item_new_with_label(audio_tracks[i]);
            g_object_set_data(G_OBJECT(item), "track", GINT_TO_POINTER(i + 1));
            g_signal_connect(item, "activate", G_CALLBACK(on_audio_track_selected), ui);
            gtk_menu_shell_append(GTK_MENU_SHELL(ui->audio_menu), item);
        }
        player_free_track_list(audio_tracks, audio_count);
    }
    gtk_widget_show_all(ui->audio_menu);
    
    /* Update Subtitle Menu */
    clear_menu(ui->subtitle_menu);
    
    int sub_count = 0;
    char **sub_tracks = player_get_subtitle_track_list(ui->player, &sub_count);
    
    if (sub_count == 0) {
        GtkWidget *item = gtk_menu_item_new_with_label("None available");
        gtk_widget_set_sensitive(item, FALSE);
        gtk_menu_shell_append(GTK_MENU_SHELL(ui->subtitle_menu), item);
    } else {
        GtkWidget *sub_disable_item = gtk_menu_item_new_with_mnemonic("_Disable");
        g_signal_connect(sub_disable_item, "activate", G_CALLBACK(on_subtitle_disable), ui);
        gtk_menu_shell_append(GTK_MENU_SHELL(ui->subtitle_menu), sub_disable_item);
        gtk_menu_shell_append(GTK_MENU_SHELL(ui->subtitle_menu), gtk_separator_menu_item_new());

        for (int i = 0; i < sub_count; i++) {
            GtkWidget *item = gtk_menu_item_new_with_label(sub_tracks[i]);
            g_object_set_data(G_OBJECT(item), "track", GINT_TO_POINTER(i + 1));
            g_signal_connect(item, "activate", G_CALLBACK(on_subtitle_track_selected), ui);
            gtk_menu_shell_append(GTK_MENU_SHELL(ui->subtitle_menu), item);
        }
        player_free_track_list(sub_tracks, sub_count);
    }
    gtk_widget_show_all(ui->subtitle_menu);
}

static void create_menubar(AppUI *ui)
{
    ui->menubar = gtk_menu_bar_new();
    
    GtkAccelGroup *accel_group = gtk_accel_group_new();
    gtk_window_add_accel_group(GTK_WINDOW(ui->window), accel_group);
    
    /* File Menu */
    GtkWidget *file_menu = gtk_menu_new();
    GtkWidget *file_item = gtk_menu_item_new_with_mnemonic("_File");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_menu);
    
    GtkWidget *open_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL);
    g_signal_connect(open_item, "activate", G_CALLBACK(on_file_open), ui);
    gtk_widget_add_accelerator(open_item, "activate", accel_group, GDK_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), open_item);
    
    GtkWidget *open_dir_item = gtk_menu_item_new_with_mnemonic("Open _Folder...");
    g_signal_connect(open_dir_item, "activate", G_CALLBACK(on_file_open_directory), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), open_dir_item);
    
    GtkWidget *open_url_item = gtk_menu_item_new_with_mnemonic("Open _URL...");
    g_signal_connect(open_url_item, "activate", G_CALLBACK(on_file_open_url), ui);
    gtk_widget_add_accelerator(open_url_item, "activate", accel_group, GDK_l, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), open_url_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), gtk_separator_menu_item_new());
    
    ui->recent_menu = gtk_recent_chooser_menu_new_for_manager(ui->recent_manager);
    GtkRecentFilter *filter = gtk_recent_filter_new();
    gtk_recent_filter_add_mime_type(filter, "video/*");
    gtk_recent_filter_add_mime_type(filter, "audio/*");
    gtk_recent_chooser_set_filter(GTK_RECENT_CHOOSER(ui->recent_menu), filter);
    gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(ui->recent_menu), FALSE);
    gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(ui->recent_menu), GTK_RECENT_SORT_MRU);
    g_signal_connect(ui->recent_menu, "item-activated", G_CALLBACK(on_recent_item_activated), ui);
    
    GtkWidget *recent_item = gtk_menu_item_new_with_mnemonic("_Recent Files");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(recent_item), ui->recent_menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), recent_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), gtk_separator_menu_item_new());
    
    GtkWidget *save_playlist_item = gtk_menu_item_new_with_mnemonic("_Save Playlist...");
    g_signal_connect(save_playlist_item, "activate", G_CALLBACK(on_file_save_playlist), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save_playlist_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), gtk_separator_menu_item_new());
    
    GtkWidget *quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
    g_signal_connect(quit_item, "activate", G_CALLBACK(on_file_quit), ui);
    gtk_widget_add_accelerator(quit_item, "activate", accel_group, GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_widget_add_accelerator(quit_item, "activate", accel_group, GDK_q, 0, 0); 
    gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), file_item);
    
    /* Playback Menu */
    GtkWidget *playback_menu = gtk_menu_new();
    GtkWidget *playback_item = gtk_menu_item_new_with_mnemonic("_Playback");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(playback_item), playback_menu);
    
    GtkWidget *play_pause_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_PLAY, NULL);
    gtk_menu_item_set_label(GTK_MENU_ITEM(play_pause_item), "_Play/Pause");
    g_signal_connect(play_pause_item, "activate", G_CALLBACK(on_playback_play_pause), ui);
    gtk_widget_add_accelerator(play_pause_item, "activate", accel_group, GDK_space, 0, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), play_pause_item);
    
    GtkWidget *stop_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_STOP, NULL);
    gtk_menu_item_set_label(GTK_MENU_ITEM(stop_item), "_Stop");
    g_signal_connect(stop_item, "activate", G_CALLBACK(on_playback_stop), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), stop_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), gtk_separator_menu_item_new());
    
    GtkWidget *prev_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS, NULL);
    g_signal_connect(prev_item, "activate", G_CALLBACK(on_playback_prev), ui);
    gtk_widget_add_accelerator(prev_item, "activate", accel_group, GDK_Page_Up, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), prev_item);
    
    GtkWidget *next_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_NEXT, NULL);
    g_signal_connect(next_item, "activate", G_CALLBACK(on_playback_next), ui);
    gtk_widget_add_accelerator(next_item, "activate", accel_group, GDK_Page_Down, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), next_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), gtk_separator_menu_item_new());
    
    /* Seek Submenu */
    GtkWidget *seek_menu = gtk_menu_new();
    GtkWidget *seek_item = gtk_menu_item_new_with_mnemonic("_Seek");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(seek_item), seek_menu);
    
    GtkWidget *seek_fwd_item = gtk_menu_item_new_with_mnemonic("Forward 10s");
    g_signal_connect(seek_fwd_item, "activate", G_CALLBACK(on_playback_seek_forward), ui);
    gtk_widget_add_accelerator(seek_fwd_item, "activate", accel_group, GDK_Right, 0, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(seek_menu), seek_fwd_item);
    
    GtkWidget *seek_back_item = gtk_menu_item_new_with_mnemonic("Backward 10s");
    g_signal_connect(seek_back_item, "activate", G_CALLBACK(on_playback_seek_backward), ui);
    gtk_widget_add_accelerator(seek_back_item, "activate", accel_group, GDK_Left, 0, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(seek_menu), seek_back_item);
    
    GtkWidget *frame_step_item = gtk_menu_item_new_with_mnemonic("_Frame Step");
    g_signal_connect(frame_step_item, "activate", G_CALLBACK(on_playback_frame_step), ui);
    gtk_widget_add_accelerator(frame_step_item, "activate", accel_group, GDK_period, 0, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(seek_menu), frame_step_item);
    
    GtkWidget *goto_time_item = gtk_menu_item_new_with_mnemonic("_Go to Time...");
    g_signal_connect(goto_time_item, "activate", G_CALLBACK(on_playback_goto_time), ui);
    gtk_widget_add_accelerator(goto_time_item, "activate", accel_group, GDK_g, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(seek_menu), goto_time_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), seek_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), gtk_separator_menu_item_new());
    
    GtkWidget *speed_item = gtk_menu_item_new_with_mnemonic("Playback S_peed...");
    g_signal_connect(speed_item, "activate", G_CALLBACK(on_playback_speed), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), speed_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), gtk_separator_menu_item_new());
    
    GtkWidget *ab_menu = gtk_menu_new();
    GtkWidget *ab_item = gtk_menu_item_new_with_mnemonic("A-B _Loop");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(ab_item), ab_menu);
    
    GtkWidget *ab_a_item = gtk_menu_item_new_with_mnemonic("Set Point _A");
    g_signal_connect(ab_a_item, "activate", G_CALLBACK(on_playback_ab_loop_a), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(ab_menu), ab_a_item);
    
    GtkWidget *ab_b_item = gtk_menu_item_new_with_mnemonic("Set Point _B");
    g_signal_connect(ab_b_item, "activate", G_CALLBACK(on_playback_ab_loop_b), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(ab_menu), ab_b_item);
    
    GtkWidget *ab_clear_item = gtk_menu_item_new_with_mnemonic("_Clear Loop");
    g_signal_connect(ab_clear_item, "activate", G_CALLBACK(on_playback_ab_loop_clear), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(ab_menu), ab_clear_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(playback_menu), ab_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), playback_item);
    
    /* Audio Menu */
    GtkWidget *audio_root_menu = gtk_menu_new();
    GtkWidget *audio_item = gtk_menu_item_new_with_mnemonic("_Audio");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(audio_item), audio_root_menu);
    
    GtkWidget *audio_tracks_item = gtk_menu_item_new_with_mnemonic("_Select Track");
    ui->audio_menu = gtk_menu_new();
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(audio_tracks_item), ui->audio_menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(audio_root_menu), audio_tracks_item);
    
    GtkWidget *audio_placeholder = gtk_menu_item_new_with_label("None available");
    gtk_widget_set_sensitive(audio_placeholder, FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->audio_menu), audio_placeholder);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(audio_root_menu), gtk_separator_menu_item_new());
    
    ui->mute_item = gtk_check_menu_item_new_with_mnemonic("_Muted");
    g_signal_connect(ui->mute_item, "toggled", G_CALLBACK(on_audio_mute), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(audio_root_menu), ui->mute_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), audio_item);
    
    /* Video Menu */
    GtkWidget *video_menu = gtk_menu_new();
    GtkWidget *video_item = gtk_menu_item_new_with_mnemonic("_Video");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(video_item), video_menu);
    
    /* Subtitles Submenu */
    GtkWidget *subtitle_root_menu = gtk_menu_new();
    GtkWidget *subtitle_item = gtk_menu_item_new_with_mnemonic("_Subtitles");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(subtitle_item), subtitle_root_menu);
    
    GtkWidget *sub_tracks_item = gtk_menu_item_new_with_mnemonic("_Select Track");
    ui->subtitle_menu = gtk_menu_new();
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(sub_tracks_item), ui->subtitle_menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(subtitle_root_menu), sub_tracks_item);
    
    GtkWidget *sub_placeholder = gtk_menu_item_new_with_label("None available");
    gtk_widget_set_sensitive(sub_placeholder, FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->subtitle_menu), sub_placeholder);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(subtitle_root_menu), gtk_separator_menu_item_new());
    
    GtkWidget *sub_load_item = gtk_menu_item_new_with_mnemonic("_Load External...");
    g_signal_connect(sub_load_item, "activate", G_CALLBACK(on_subtitle_load), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(subtitle_root_menu), sub_load_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(video_menu), subtitle_item);
    
    /* Chapters Submenu */
    ui->chapter_menu = gtk_menu_new();
    GtkWidget *chapter_item = gtk_menu_item_new_with_mnemonic("_Chapters");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(chapter_item), ui->chapter_menu);
    
    GtkWidget *chapter_placeholder = gtk_menu_item_new_with_label("(No chapters)");
    gtk_widget_set_sensitive(chapter_placeholder, FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->chapter_menu), chapter_placeholder);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(video_menu), chapter_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(video_menu), gtk_separator_menu_item_new());
    
    /* Aspect ratio submenu */
    ui->aspect_menu = gtk_menu_new();
    GtkWidget *aspect_item = gtk_menu_item_new_with_mnemonic("_Aspect Ratio");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(aspect_item), ui->aspect_menu);
    
    const char *aspects[] = {"Auto", "4:3", "16:9", "16:10", "1.85:1", "2.35:1", NULL};
    const char *aspect_vals[] = {"-1", "4:3", "16:9", "16:10", "1.85:1", "2.35:1", NULL};
    
    for (int i = 0; aspects[i] != NULL; i++) {
        GtkWidget *ar_item = gtk_menu_item_new_with_label(aspects[i]);
        g_object_set_data(G_OBJECT(ar_item), "aspect", (gpointer)aspect_vals[i]);
        g_signal_connect(ar_item, "activate", G_CALLBACK(on_aspect_ratio_selected), ui);
        gtk_menu_shell_append(GTK_MENU_SHELL(ui->aspect_menu), ar_item);
    }
    gtk_menu_shell_append(GTK_MENU_SHELL(video_menu), aspect_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(video_menu), gtk_separator_menu_item_new());
    
    GtkWidget *screenshot_item = gtk_menu_item_new_with_mnemonic("_Screenshot");
    g_signal_connect(screenshot_item, "activate", G_CALLBACK(on_view_screenshot), ui);
    gtk_widget_add_accelerator(screenshot_item, "activate", accel_group, GDK_s, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(video_menu), screenshot_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), video_item);
    
    /* View Menu */
    GtkWidget *view_menu = gtk_menu_new();
    GtkWidget *view_item = gtk_menu_item_new_with_mnemonic("_View");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_item), view_menu);
    
    GtkWidget *fullscreen_item = gtk_menu_item_new_with_mnemonic("_Fullscreen");
    g_signal_connect(fullscreen_item, "activate", G_CALLBACK(on_view_fullscreen), ui);
    gtk_widget_add_accelerator(fullscreen_item, "activate", accel_group, GDK_f, 0, GTK_ACCEL_VISIBLE);
    gtk_widget_add_accelerator(fullscreen_item, "activate", accel_group, GDK_F11, 0, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), fullscreen_item);
    
    GtkWidget *playlist_toggle_item = gtk_check_menu_item_new_with_mnemonic("_Playlist");
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(playlist_toggle_item), ui->prefs->show_playlist);
    g_signal_connect(playlist_toggle_item, "toggled", G_CALLBACK(on_view_playlist), ui);
    gtk_widget_add_accelerator(playlist_toggle_item, "activate", accel_group, GDK_p, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
    gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), playlist_toggle_item);
    
    GtkWidget *on_top_item = gtk_check_menu_item_new_with_mnemonic("Always on _Top");
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(on_top_item), ui->always_on_top);
    g_signal_connect(on_top_item, "toggled", G_CALLBACK(on_view_always_on_top), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), on_top_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), view_item);
    
    /* Tools Menu */
    GtkWidget *tools_menu = gtk_menu_new();
    GtkWidget *tools_item = gtk_menu_item_new_with_mnemonic("_Tools");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(tools_item), tools_menu);
    
    GtkWidget *plugins_menu = plugin_manager_get_menu(ui->plugin_manager);
    GtkWidget *plugins_item = gtk_menu_item_new_with_mnemonic("_Plugins");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(plugins_item), plugins_menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(tools_menu), plugins_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(tools_menu), gtk_separator_menu_item_new());
    
    GtkWidget *prefs_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL);
    g_signal_connect(prefs_item, "activate", G_CALLBACK(on_view_preferences), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(tools_menu), prefs_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), tools_item);
    
    /* Help Menu */
    GtkWidget *help_menu = gtk_menu_new();
    GtkWidget *help_item = gtk_menu_item_new_with_mnemonic("_Help");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_item), help_menu);
    gtk_menu_item_set_right_justified(GTK_MENU_ITEM(help_item), FALSE);
    
    GtkWidget *about_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
    g_signal_connect(about_item, "activate", G_CALLBACK(on_help_about), ui);
    gtk_menu_shell_append(GTK_MENU_SHELL(help_menu), about_item);
    
    gtk_menu_shell_append(GTK_MENU_SHELL(ui->menubar), help_item);
}

/* Menu callbacks */

static void on_audio_mute(GtkMenuItem *item, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    player_set_muted(ui->player, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
}

static void on_file_open(GtkMenuItem *item, gpointer data)
{
    (void)item;
    ui_open_file((AppUI *)data);
}

static void on_file_open_directory(GtkMenuItem *item, gpointer data)
{
    (void)item;
    ui_open_directory((AppUI *)data);
}

static void on_file_open_url(GtkMenuItem *item, gpointer data)
{
    (void)item;
    ui_open_url((AppUI *)data);
}

static void on_file_save_playlist(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    
    char *filename = dialogs_save_playlist(GTK_WINDOW(ui->window), ui->prefs);
    if (filename) {
        playlist_save_to_file(ui->playlist, filename);
        g_free(filename);
    }
}

static void on_file_quit(GtkMenuItem *item, gpointer data)
{
    (void)item;
    (void)data;
    gtk_main_quit();
}

static void on_playback_play_pause(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    
    gboolean eof = player_get_eof_reached(ui->player);
    gboolean idle = player_is_idle(ui->player);
    
    fprintf(stderr, "DEBUG: on_playback_play_pause triggered. eof=%d, idle=%d\n", eof, idle);
    
    if (eof) {
        fprintf(stderr, "DEBUG: EOF reached, seeking to 0 and playing\n");
        player_seek_absolute(ui->player, 0);
        player_play(ui->player);
        controls_update_pause_state(ui->controls, FALSE);
    } else if (idle) {
        fprintf(stderr, "DEBUG: Player idle, re-triggering playback\n");
        
        /* If mpv playlist is empty, refill it from our UI playlist */
        if (player_get_playlist_count(ui->player) == 0) {
            fprintf(stderr, "DEBUG: mpv playlist empty, refilling\n");
            playlist_refill_player(ui->playlist);
        }
        
        if (playlist_get_count(ui->playlist) > 0) {
            int index = playlist_get_current_index(ui->playlist);
            if (index < 0) index = 0;
            playlist_play_index(ui->playlist, index);
            player_play(ui->player);
            controls_update_pause_state(ui->controls, FALSE);
        }
    } else {
        fprintf(stderr, "DEBUG: Normal playback, toggling pause\n");
        player_toggle_pause(ui->player);
    }
}

static void on_playback_stop(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_stop(ui->player);
    
    /* Immediately reset UI */
    controls_reset(ui->controls);
    ui_update_title(ui, "Kino");
}

static void on_playback_prev(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    playlist_play_prev(ui->playlist);
}

static void on_playback_next(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    playlist_play_next(ui->playlist);
}

static void on_chapter_selected(GtkMenuItem *item, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    int index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "chapter-index"));
    player_set_chapter(ui->player, index);
}

static void update_chapter_menu(AppUI *ui)
{
    if (!ui || !ui->chapter_menu) return;
    if (ui->prefs && !ui->prefs->enable_chapters) return;
    
    /* Clear old menu */
    GList *children = gtk_container_get_children(GTK_CONTAINER(ui->chapter_menu));
    for (GList *iter = children; iter != NULL; iter = iter->next) {
        gtk_widget_destroy(GTK_WIDGET(iter->data));
    }
    g_list_free(children);
    
    int count = 0;
    char **chapters = player_get_chapter_list(ui->player, &count);
    double *times = player_get_chapter_times(ui->player, &count);
    
    /* Sync markers to controls */
    controls_set_chapters(ui->controls, count, times);
    if (times) g_free(times);
    
    if (count > 0 && chapters) {
        int current = player_get_current_chapter(ui->player);
        for (int i = 0; i < count; i++) {
            GtkWidget *item = gtk_image_menu_item_new_with_label(chapters[i]);
            
            if (i == current) {
                GtkWidget *img = gtk_image_new_from_stock(GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU);
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img);
                gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item), TRUE);
            }
            
            g_object_set_data(G_OBJECT(item), "chapter-index", GINT_TO_POINTER(i));
            g_signal_connect(item, "activate", G_CALLBACK(on_chapter_selected), ui);
            gtk_menu_shell_append(GTK_MENU_SHELL(ui->chapter_menu), item);
        }
        player_free_track_list(chapters, count);
    } else {
        GtkWidget *placeholder = gtk_menu_item_new_with_label("(No chapters)");
        gtk_widget_set_sensitive(placeholder, FALSE);
        gtk_menu_shell_append(GTK_MENU_SHELL(ui->chapter_menu), placeholder);
    }
    
    gtk_widget_show_all(ui->chapter_menu);
}

static void on_playback_seek_forward(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_seek(ui->player, 10);
}

static void on_playback_seek_backward(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_seek(ui->player, -10);
}

static void on_playback_frame_step(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_frame_step(ui->player);
}

static void on_playback_goto_time(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    
    double current = player_get_position(ui->player);
    double duration = player_get_duration(ui->player);
    
    double new_time = dialogs_goto_time(GTK_WINDOW(ui->window), current, duration);
    if (new_time >= 0) {
        player_seek_absolute(ui->player, new_time);
    }
}

static void on_playback_speed(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    
    double current = player_get_speed(ui->player);
    double new_speed = dialogs_select_speed(GTK_WINDOW(ui->window), current);
    if (new_speed > 0) {
        player_set_speed(ui->player, new_speed);
    }
}

static void on_playback_ab_loop_a(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_set_ab_loop_a(ui->player);
}

static void on_playback_ab_loop_b(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_set_ab_loop_b(ui->player);
}

static void on_playback_ab_loop_clear(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_clear_ab_loop(ui->player);
}

static void on_audio_track_selected(GtkMenuItem *item, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    int track = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "track"));
    player_set_audio_track(ui->player, track);
}

static void on_subtitle_track_selected(GtkMenuItem *item, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    int track = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "track"));
    player_set_subtitle_track(ui->player, track);
}

static void on_subtitle_load(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    ui_load_subtitle(ui);
}

static void on_subtitle_disable(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    player_set_subtitle_track(ui->player, 0); /* 0 = no subtitles */
}

static void on_view_fullscreen(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    ui_toggle_fullscreen(ui);
}

static void on_view_playlist(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    ui_toggle_playlist(ui);
}

static void on_view_always_on_top(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    ui_toggle_always_on_top(ui);
}

static void on_view_screenshot(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    /* Use instant screenshot (saves to configured directory) */
    player_screenshot(ui->player);
}

static void on_view_preferences(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    if (dialogs_show_preferences(GTK_WINDOW(ui->window), ui->prefs, ui->plugin_manager)) {
        /* Apply changes immediately */
        if (!ui->is_fullscreen) {
            if (ui->prefs->hide_cursor_windowed) {
                if (ui->auto_hide_timer_id == 0) {
                    ui->auto_hide_timer_id = g_timeout_add(3000, auto_hide_timer_cb, ui);
                }
            } else {
                if (ui->auto_hide_timer_id > 0) {
                    g_source_remove(ui->auto_hide_timer_id);
                    ui->auto_hide_timer_id = 0;
                }
                /* Restore cursor and controls */
                GdkWindow *window = gtk_widget_get_window(ui->video_area);
                if (window) gdk_window_set_cursor(window, NULL);
                gtk_widget_show(controls_get_widget(ui->controls));
            }
        }
        
        /* Apply Focus Rect setting (GTK2 specific hack) */
        if (ui->prefs->hide_focus_rect) {
            gtk_rc_parse_string("style \"no-focus-rect\" { GtkWidget::focus-line-width = 0 GtkWidget::focus-padding = 0 } widget \"*\" style \"no-focus-rect\"");
        } else {
            gtk_rc_parse_string("style \"default-focus-rect\" { GtkWidget::focus-line-width = 1 GtkWidget::focus-padding = 1 } widget \"*\" style \"default-focus-rect\"");
        }
        gtk_widget_reset_rc_styles(ui->window);
        gtk_widget_queue_draw(ui->window);
        
        /* Apply OSD setting */
        player_set_option_string(ui->player, "osd-level", ui->prefs->enable_osd ? "1" : "0");
        player_set_option_string(ui->player, "osd-bar", ui->prefs->enable_osd ? "yes" : "no");
        
        /* Apply mpv.conf if changed - parse and apply each option */
        if (ui->prefs->mpv_config_path && g_file_test(ui->prefs->mpv_config_path, G_FILE_TEST_EXISTS)) {
            /* First, reset common properties to defaults to avoid "bleeding" from previous configs */
            player_set_option_string(ui->player, "brightness", "0");
            player_set_option_string(ui->player, "contrast", "0");
            player_set_option_string(ui->player, "saturation", "0");
            player_set_option_string(ui->player, "gamma", "0");
            player_set_option_string(ui->player, "hue", "0");
            
            player_set_option_string(ui->player, "osd-color", "#FFFFFFFF");
            player_set_option_string(ui->player, "osd-border-color", "#FF000000");
            player_set_option_string(ui->player, "osd-shadow-color", "#80000000");
            player_set_option_string(ui->player, "osd-font-size", "55");
            player_set_option_string(ui->player, "osd-border-size", "3");
            player_set_option_string(ui->player, "osd-shadow-offset", "0");
            
            FILE *fp = fopen(ui->prefs->mpv_config_path, "r");
            if (fp) {
                char line[512];
                int applied = 0;
                while (fgets(line, sizeof(line), fp)) {
                    /* Strip newline */
                    char *nl = strchr(line, '\n');
                    if (nl) *nl = '\0';
                    
                    /* Skip comments and empty lines */
                    char *p = line;
                    while (*p == ' ' || *p == '\t') p++;
                    if (*p == '#' || *p == '\0') continue;
                    
                    /* Find '=' separator */
                    char *eq = strchr(p, '=');
                    if (eq) {
                        *eq = '\0';
                        char *key = p;
                        char *value = eq + 1;
                        
                        /* Trim trailing spaces from key */
                        char *k_end = key + strlen(key) - 1;
                        while (k_end > key && (*k_end == ' ' || *k_end == '\t')) *k_end-- = '\0';
                        
                        /* Trim leading spaces from value */
                        while (*value == ' ' || *value == '\t') value++;
                        
                        /* Remove surrounding quotes if present */
                        size_t vlen = strlen(value);
                        if (vlen >= 2 && ((value[0] == '\'' && value[vlen-1] == '\'') ||
                                          (value[0] == '"' && value[vlen-1] == '"'))) {
                            value[vlen-1] = '\0';
                            value++;
                        }
                        
                        player_set_option_string(ui->player, key, value);
                        applied++;
                    }
                }
                fclose(fp);
                
                /* Show feedback with count */
                char msg[64];
                snprintf(msg, sizeof(msg), "Applied %d config options", applied);
                const char *msg_cmd[] = {"show-text", msg, "2000", NULL};
                mpv_command_async(player_get_mpv_handle(ui->player), 0, msg_cmd);
            }
        }
        
        /* Apply Screenshot Format */
        if (ui->prefs->screenshot_format) {
            player_set_option_string(ui->player, "screenshot-format", ui->prefs->screenshot_format);
        }
        
        /* Apply Screenshot Dir */
        if (ui->prefs->screenshot_directory) {
            player_set_option_string(ui->player, "screenshot-directory", ui->prefs->screenshot_directory);
        }

        /* Show feedback */
        const char *saved_cmd[] = {"show-text", "Preferences saved", "1500", NULL};
        mpv_command_async(player_get_mpv_handle(ui->player), 0, saved_cmd);
    }
}

static void on_aspect_ratio_selected(GtkMenuItem *item, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    const char *aspect = g_object_get_data(G_OBJECT(item), "aspect");
    player_set_aspect_ratio(ui->player, aspect);
}

static void on_help_about(GtkMenuItem *item, gpointer data)
{
    (void)item;
    AppUI *ui = (AppUI *)data;
    dialogs_show_about(GTK_WINDOW(ui->window));
}

static void on_controls_play_pause(gpointer data)
{
    on_playback_play_pause(NULL, data);
}

static void on_recent_item_activated(GtkRecentChooser *chooser, gpointer data)
{
    AppUI *ui = (AppUI *)data;
    char *uri = gtk_recent_chooser_get_current_uri(chooser);
    if (uri) {
        char *path = g_filename_from_uri(uri, NULL, NULL);
        if (path) {
            add_path_to_playlist(ui, path, TRUE);
            if (playlist_get_count(ui->playlist) > 0) {
                playlist_play_index(ui->playlist, 0);
            }
            g_free(path);
        } else if (strstr(uri, "://")) {
            /* Handle URL */
            playlist_clear(ui->playlist);
            playlist_add_file(ui->playlist, uri, FALSE);
            playlist_play_index(ui->playlist, 0);
        }
        g_free(uri);
    }
}

/* Plugin UI Helpers */
void ui_set_video_area_visible(AppUI *ui, gboolean visible)
{
    if (!ui || !ui->video_container) return;
    
    if (visible) {
        gtk_widget_show(ui->video_container);
        gtk_widget_set_no_show_all(ui->video_container, FALSE);
    } else {
        gtk_widget_hide(ui->video_container);
        gtk_widget_set_no_show_all(ui->video_container, TRUE);
    }
}

void ui_set_window_size(AppUI *ui, int width, int height)
{
    if (!ui || !ui->window) return;
    gtk_window_resize(GTK_WINDOW(ui->window), width, height);
}


void ui_restart(AppUI *ui)
{
    (void)ui;
    
    /* Get the path to the current executable */
    char *bin_path = NULL;
    
    /* If we are installed, use the installed path */
    if (g_file_test("/usr/local/bin/gtk2-mpv-player", G_FILE_TEST_EXISTS)) {
        bin_path = g_strdup("/usr/local/bin/gtk2-mpv-player");
    } else {
        /* Otherwise try to find it relative to current dir */
        bin_path = g_build_filename(".", "gtk2-mpv-player", NULL);
    }
    
    printf("Restarting application via %s...\n", bin_path);
    
    char *argv[] = {bin_path, NULL};
    execvp(bin_path, argv);
    
    /* If execvp fails */
    perror("execvp");
    g_free(bin_path);
}


void ui_open_scripts_folder(AppUI *ui)
{
    (void)ui;
    
    const char *config_dir = g_get_user_config_dir();
    char *scripts_dir = g_build_filename(config_dir, "gtk2-media-player", "scripts", NULL);
    
    /* Ensure it exists */
    g_mkdir_with_parents(scripts_dir, 0755);
    
    printf("Opening scripts directory: %s\n", scripts_dir);
    
    char *cmd = g_strdup_printf("xdg-open '%s'", scripts_dir);
    int ret = system(cmd);
    (void)ret; /* Suppress unused result warning */
    
    g_free(cmd);
    g_free(scripts_dir);
}

void ui_show_script_manager(AppUI *ui)
{
    if (!ui) return;
    dialogs_show_script_manager(GTK_WINDOW(ui->window), ui->player);
}

