
#define LV_USE_SDL 1
#define LV_FONT_DEFAULT &roboto_medium_36

#include <stdio.h>
#include "esp_wifi.h"
#include "ihm.h"
#include "mqtt_client.h"
#include "backends.h"
#include <unistd.h>
#include "driver_backends.h"
#include "simulator_util.h"
#include "simulator_settings.h"
#include "esp_log.h"
#include "eventsManager.h"
#include "RemindMe.h"
#include "ihm_gateway.h"
#include "platform_detect.h"

esp_mqtt_client_handle_t client;
SemaphoreHandle_t lvgl_mux;

/* contains the name of the selected backend if user
 * has specified one on the command line */
static char *selected_backend;

/* Global simulator settings, defined in lv_linux_backend.c */
extern simulator_settings_t settings;

void die(const char *msg, ...)
{
    va_list args;

    va_start(args, msg);
    vfprintf(stderr, msg, args);
    va_end(args);

    exit(EXIT_FAILURE);

}

/**
 * @brief Print LVGL version
 */
static void print_lvgl_version(void)
{
    fprintf(stdout, "%d.%d.%d-%s\n",
            LVGL_VERSION_MAJOR,
            LVGL_VERSION_MINOR,
            LVGL_VERSION_PATCH,
            LVGL_VERSION_INFO);
}

/**
 * @brief Print usage information
 */
static void print_usage(void)
{
    fprintf(stdout, "\nlvglsim [-V] [-B] [-b backend_name] [-W window_width] [-H window_height]\n\n");
    fprintf(stdout, "-V print LVGL version\n");
    fprintf(stdout, "-B list supported backends\n");
}

/**
 * @brief Configure simulator
 * @description process arguments recieved by the program to select
 * appropriate options
 * @param argc the count of arguments in argv
 * @param argv The arguments
 */
static void configure_simulator(int argc, char **argv)
{
    int opt = 0;

    selected_backend = NULL;
    driver_backends_register();

    const char *env_w = getenv("LV_SIM_WINDOW_WIDTH");
    const char *env_h = getenv("LV_SIM_WINDOW_HEIGHT");
    /* Default values */
    settings.window_width = atoi(env_w ? env_w : "1024");
    settings.window_height = atoi(env_h ? env_h : "600");

    /* Parse the command-line options. */
    while ((opt = getopt (argc, argv, "b:fmW:H:BVh")) != -1) {
        switch (opt) {
        case 'h':
            print_usage();
            exit(EXIT_SUCCESS);
            break;
        case 'V':
            print_lvgl_version();
            exit(EXIT_SUCCESS);
            break;
        case 'B':
            driver_backends_print_supported();
            exit(EXIT_SUCCESS);
            break;
        case 'b':
            if (driver_backends_is_supported(optarg) == 0) {
                die("error no such backend: %s\n", optarg);
            }
            selected_backend = strdup(optarg);
            break;
        case 'W':
            settings.window_width = atoi(optarg);
            break;
        case 'H':
            settings.window_height = atoi(optarg);
            break;
        case ':':
            print_usage();
            die("Option -%c requires an argument.\n", optopt);
            break;
        case '?':
            print_usage();
            die("Unknown option -%c.\n", optopt);
        }
    }
}

int app_main(int argc, char *argv[]) {
    // Détecte la plateforme
    bool isPC = platform_is_pc();

    // Init gateway
    ihm_gateway_init();
    startEvtManager();

    if (isPC) {
        // PC / SDL : loop dans le thread principal
        /* Initialize LVGL. */
        lv_init();
        configure_simulator(argc, argv);
        /* Initialize the configured backend */
        if (driver_backends_init_backend(selected_backend) == -1) {
            die("Failed to initialize display backend");
        }
        lv_sdl_mouse_create();
        lv_sdl_keyboard_create();
        lv_sdl_mousewheel_create();
        lv_sdl_mousewheel_create();

        time_t now;
        struct tm timeinfo;
        time(&now);
        localtime_r(&now, &timeinfo);

        lv_subject_init_pointer(&timeSubj, &timeinfo);

        drawIhm(NULL);
    } else {
        // ESP32 : créer task FreeRTOS
        xTaskCreate(drawIhm, "LVGL", 256*1024, NULL, 3, NULL);
    }

    // Exemple : poster un événement
    xIHMEvent_t *evt = malloc(sizeof(*evt));
    evt->eEventType = 1;
    evt->pvData = strdup("Hello LVGL");
    evt->bNeedToFreeData = true;
    ihm_gateway_post_event(evt);

    return 0;
}


int app_main1(int argc, char *argv[])
{
    /* code */
    printf("hello\n");
    lvgl_mux = xSemaphoreCreateRecursiveMutex();
    assert(lvgl_mux);

    init_display_ihm();


    //size_t watermark = uxTaskGetStackHighWaterMark(NULL);
    //ESP_LOGI("STACK", "Remaining stack: %d bytes", watermark);


    /*lv_timer_t *clock_timer = lv_timer_create(clock_timer_cb, 1000, NULL);*/

    //draw_ihm();
    startEvtManager();

    int count=0;
    events=get_events(&count);
    if (!events)
    {
        ESP_LOGE("test", "Aucun événement chargé");
        //return 0;
    } // Parcourir tous les événements
    for (int i = 0; i < count; i++)
    {
        ESP_LOGI("test", "%s", events[i].affichage);
    }

    xTaskCreate(drawIhm, "LVGL", 14 * 1024, getIHMQueueHandle(), 3, NULL);
    //drawIhm(getIHMQueueHandle());
    send_event(EVT_WIFI_CONNECTED,NULL);
    meteodailyforecast_data dts = {
        .datetime= time(NULL),
        .isValid= true,
        .previsions = {
            .desc = "Ensoleillé",
            .icon = "p4j",
            .max = 12.40f,
            .min = 3.30f
        }
    };
    /*
    extern lv_subject_t forecastD1Subj;
    extern lv_subject_t forecastD2Subj;
    extern lv_subject_t forecastD3Subj;
    ESP_LOGI("test_ihm", "Setting forecastD1Subj");

    lv_subject_set_pointer(&forecastD1Subj, &dts);
    lv_subject_set_pointer(&forecastD2Subj, &dts);
    lv_subject_set_pointer(&forecastD3Subj, &dts);
    */

    /* Enter the run loop of the selected backend */
    driver_backends_run_loop();

    //drawIhm(getIHMQueueHandle());

    return 0;
}

