#define __USE_GNU
#define _GNU_SOURCE
#include "core/lvgl/lvgl.h"
#include "core/lvgl_driver/fbdev.h"
#include "core/lvgl_driver/evdev.h"
#include "core/lvgl_driver/lv_port_indev.h"
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
//#include <pthread.h>
#include <sched.h> 
#include "ui/ui_manager.h"
#include "lvgl_app.h"
#include "app_config.h"

#include "data/key_manager.h"
#include "app/app_main_menu.h"
#include "app/app_home_page.h"
#include "app/app_devinfo_page.h"
#include "app/components/app_input_pwd.h"

pthread_mutex_t mutex_lvgl_set;
lv_indev_t *my_indev = NULL;

void app_handle_event(keyValue kevent , PageType curpage)
{
    // 遍历映射数组，找到当前页面对应的处理函数
    for (uint8_t i = 0; i < g_page_event_map_size; i++) {
        if (g_page_event_map[i].page_id == curpage) {
            g_page_event_map[i].handler(kevent);
            return;
        }
    }


}

void* lvgl_thread(void* arg)
{
    prctl(PR_SET_NAME, "lvgl_thread");
    //static int valechange_event = 1;
    //da_lvgl_init();
    ui_manager_init();

    ui_manager_switch_page(NULL);
     // 定义互斥锁;
    pthread_mutex_init(&mutex_lvgl_set, NULL); 
    keyValue kevent ;
    PageType curpage;
    //Display();
    while (1)
    {
        kevent = key_manager_get_event();

        if (kevent != KEY_DATA_NULL)
        {
            // printf("%s not KEY_DATA_NULL\n", __FUNCTION__);
            key_manager_reset();
            curpage = ui_manager_get_curpage();
            //printf("%s curpage : %d\n", __FUNCTION__, curpage);
            app_handle_event(kevent , curpage);
            // 处理完后多休眠一点，避免抖动
            usleep(200000); // 200ms
        }
        else
        {
            // 无事件时休眠更长
            usleep(50000);  // 50ms
        }

        lv_task_handler(); // LVGL的事务处理  
        
    }

    return 0;
}

// 提供一个启动 LVGL 线程的函数，供外部调用
void start_lvgl_thread() {
    pthread_t tid;
    if (pthread_create(&tid, NULL, lvgl_thread, NULL) != 0) {
        perror("pthread_create");
    }
    // 可以选择是否分离线程，根据需求决定
    // pthread_detach(tid); 
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if (start_ms == 0)
    {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}