#define _DEFAULT_SOURCE
#include <gtk/gtk.h>
#include <gio/gio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "ui.h"

static gboolean forward_to_running_instance(int argc, char *argv[]) {
    GError *error = NULL;
    GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
    if (!conn) {
        if (error) g_error_free(error);
        return FALSE;
    }

    /* Check if our name is owned */
    GVariant *v = g_dbus_connection_call_sync(conn,
        "org.freedesktop.DBus",
        "/org/freedesktop/DBus",
        "org.freedesktop.DBus",
        "GetNameOwner",
        g_variant_new("(s)", "org.mpris.MediaPlayer2.gtk2_mpv_player"),
        G_VARIANT_TYPE("(s)"),
        G_DBUS_CALL_FLAGS_NONE,
        -1, NULL, &error);

    if (!v) {
        if (error) g_error_free(error);
        g_object_unref(conn);
        return FALSE;
    }
    g_variant_unref(v);

    /* Another instance is running. Forward files. */
    if (argc > 1) {
        GVariantBuilder builder;
        g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
        for (int i = 1; i < argc; i++) {
            char *abs_path = realpath(argv[i], NULL);
            g_variant_builder_add(&builder, "s", abs_path ? abs_path : argv[i]);
            if (abs_path) free(abs_path);
        }

        g_dbus_connection_call_sync(conn,
            "org.mpris.MediaPlayer2.gtk2_mpv_player",
            "/org/mpris/MediaPlayer2",
            "org.mpris.MediaPlayer2",
            "AddFiles",
            g_variant_new("(as)", &builder),
            NULL,
            G_DBUS_CALL_FLAGS_NONE,
            -1, NULL, NULL);

        /* Also raise the window */
        g_dbus_connection_call_sync(conn,
            "org.mpris.MediaPlayer2.gtk2_mpv_player",
            "/org/mpris/MediaPlayer2",
            "org.mpris.MediaPlayer2",
            "Raise",
            NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
    } else {
        /* No files, just raise */
        g_dbus_connection_call_sync(conn,
            "org.mpris.MediaPlayer2.gtk2_mpv_player",
            "/org/mpris/MediaPlayer2",
            "org.mpris.MediaPlayer2",
            "Raise",
            NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
    }

    g_object_unref(conn);
    return TRUE;
}

int main(int argc, char *argv[])
{
    /* Set numeric locale to C for libmpv */
    gtk_disable_setlocale();
    setlocale(LC_ALL, "C");

    /* Basic command line parsing */
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
            printf("Media Player v0.7\n");
            printf("Usage: %s [options] [files...]\n\n", argv[0]);
            printf("Options:\n");
            printf("  -h, --help     Show this help message\n");
            printf("  -v, --version  Show version information\n");
            printf("\nKeyboard Shortcuts:\n");
            printf("  Space          Play/Pause\n");
            printf("  S              Stop\n");
            printf("  F              Toggle Fullscreen\n");
            printf("  Left/Right     Seek -5/+5 seconds\n");
            printf("  Up/Down        Seek -60/+60 seconds\n");
            printf("  9/0            Volume Down/Up\n");
            printf("  m              Mute\n");
            return 0;
        }
        if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
            printf("Kino v9.0\n");
            return 0;
        }
    }

    /* Load preferences to check single-instance setting */
    Preferences *prefs = preferences_new();
    preferences_load(prefs);

    /* Single instance check - only if NOT opening in new window */
    if (!prefs->open_in_new_window && forward_to_running_instance(argc, argv)) {
        preferences_free(prefs);
        return 0;
    }

    /* Initialize GTK */
    gtk_init(&argc, &argv);
    
    /* Create application UI */
    AppUI *ui = ui_new();
    if (!ui) {
        fprintf(stderr, "Failed to create application UI\n");
        preferences_free(prefs);
        return 1;
    }
    
    /* Pass preferences to UI */
    ui_set_preferences(ui, prefs);
    
    /* If files were passed as arguments, load them */
    if (argc > 1) {
        Playlist *playlist = ui_get_playlist(ui);
        playlist_clear(playlist);
        
        for (int i = 1; i < argc; i++) {
            /* Add to UI playlist (which handles player loading) */
            playlist_add_file(playlist, argv[i], (i == 1) ? FALSE : TRUE);
        }
    }
    
    /* Run the application */
    ui_run(ui);
    
    /* Cleanup */
    ui_destroy(ui);
    /* prefs is freed in ui_destroy via ui_set_preferences? 
       Actually ui_set_preferences usually takes ownership or we free it here.
       Looking at previous code, ui usually handles it. 
       Wait, let me check ui.c to see how preferences are handled.
    */
    
    return 0;
}
