#include "common.h"
#include "app_device_common.h"
#include "drivers_common.h"
#include "modules_common.h"
#include "pthread_open.h"
#include "go_deploy.h"
#include "webrtcpush_config.h"
#include "webrtcpush_run.h"

#define PTHREAD_MAX 8

static pthread_t s_thread[PTHREAD_MAX]; // 全局线程句柄数组（或传参）

static int s_webrtc_index = 0; // 判断游览器是否打开

static int s_mqtt_grc = 0; // mqtt连接状态机

static void *s_args[PTHREAD_MAX] = {NULL};

int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat,
                      ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect,
                      ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3,
                      ThreadFunc thread_steering_control, ThreadFunc thread_wifi_recovery)
{

    ThreadFunc thread_funcs[] = {
        thread_exit_time,
        thread_mqtt_beat,
        thread_open_browser,
        thread_mqtt_reconnect,
        thread_time_calculation,
        thread_play_mp3,
        thread_steering_control,
        thread_wifi_recovery};

    for (int i = 0; i < PTHREAD_MAX; i++)
    {
        if (pthread_create(&s_thread[i], NULL, thread_funcs[i], s_args[i]) != 0)
        {
            my_zlog_error("创建线程 %d 失败", i);
            return i + 1;
        }
    }
    return 0;
}

// 出现意外自动停止
void *thread_exit_time(void *arg)
{
    device_serial_exit_run();//串口设备的异常退出和接收运行
    while (1)
    {
        if (get_self_control_index() == false)
        {

            delay_ms(100);
            pthread_mutex_lock(&g_exit_count_mutex);
            g_devcontrol_exit_count++;

            if(g_device_type==DEVICE_TANK0204){
                static int s_tank0204_pinval_temporary_timecount=0;
                if(g_devcontrol_exit_count<2) {
                    s_tank0204_pinval_temporary_timecount=0;
                    device_gpio_control(DEVICE_TANK0204,6,1);
                }
                    s_tank0204_pinval_temporary_timecount++;
                if(s_tank0204_pinval_temporary_timecount>200){
                    s_tank0204_pinval_temporary_timecount=201;
                    device_gpio_control(DEVICE_TANK0204,6,0);
                }
            }

            if (g_devcontrol_exit_count == 5)
            {
                device_stop(g_device_type);
            }
            else if (g_devcontrol_exit_count > 5)
            {
                g_devcontrol_exit_count = 5;
            }
            pthread_mutex_unlock(&g_exit_count_mutex);
        }
        else if (get_self_control_index() == true)
        {
            delay_ms(20);
            set_self_control_time_countfuntion();
        }
    }
    return NULL;
}

/*心跳线程处理函数，心跳发送前会像上层请求是否需要验证*/
void *thread_mqtt_beat(void *arg)
{
    my_zlog_info("thread_mqtt_beat start");
    s_webrtc_index = 1;
    delay_s(1);
    int mqtt_wait_ms = 0;
    while (!mqtt_has_connected() && mqtt_wait_ms < 15000)
    {
        delay_ms(100);
        mqtt_wait_ms += 100;
    }

    /*在这步进行检测，等mqtt连接成功后检查*/
    //     if(wifi_change_sendmqtt_init()!=0){
    //       my_zlog_error("WIFI是否更改检查相关，不会到这一步，有问题会直接重启，可能会导致重启，不会因此造成程序停止");
    //    }
    if (mqtt_has_connected()) {
        if (verify_open_index_init() != 0)
        {
            my_zlog_warn("mqtt send verify is NULL");
        }
    } else {
        my_zlog_warn("MQTT未就绪，跳过首次验证开关查询(3013)");
    }

    // 如果为相关的不需要心跳或者游览器设备，提早结束线程
    if (g_device_type == DEVICE_ROBOT_DOG0501)
    {
        my_zlog_info("device am robot and no c/c++");
        return NULL;
    }

    while (1)
    {
        delay_ms(100);
        s_mqtt_grc = mqtt_has_connected() ? 0 : 1;

        verify_open_query_poll();

        g_heartbeat_count++;
        set_tank_angle_count(); // 角度发布计时,1开始计时，0清0
        if (s_mqtt_grc == 0)
        {
            mqtt_beat_wirte(); // 心跳等发布函数，更具不同时间发布

            if (get_device_self_control_configuration_initialization() == 0)
            {
                my_zlog_info("自控配置初始化成功");
            }
        }
    }
    return NULL;
}

// 打开go_video或者浏览器
static void run_chromium_cam_loop(void)
{
    int result = system("pkill chromium");
    if (result != 0)
        my_zlog_warn("system error,chromium is close");
    delay_s(5);
    while (1) {
        if (s_webrtc_index == 1) {
            if (!browser_auto_restart_allowed()) {
                delay_ms(200);
                continue;
            }
            if (is_browser_running() == true) {
                delay_ms(200);
                continue;
            }
            my_zlog_info("open cam (Chromium fallback)");
            opencamsh();
        }
        delay_ms(200);
    }
}

void *thread_open_browser(void *arg)
{

    if (g_device_type == DEVICE_PG_GPS0403)
    {
        return NULL;
    }
    delay_s(5);
    // 检查 go_video 可执行文件是否存在
    my_zlog_info("开始检测go_video可执行文件是否存在");
    if (strcmp(g_webrtc_mode, "go") == 0 && access("/home/orangepi/go_video/go_video", F_OK) == 0)
    {
        my_zlog_info("检测到 go_video 可执行文件");

        // 检查 go_video 进程是否已经在运行
        FILE *fp = popen("pidof go_video", "r");
        if (fp != NULL)
        {
            char buf[64] = {0};
            if (fgets(buf, sizeof(buf), fp) != NULL)
            {
                // 检查是否真的有数字 PID
                int pid = atoi(buf);
                if (pid > 0)
                {
                    // 进程已经在运行，先终止
                    char kill_cmd[64];
                    snprintf(kill_cmd, sizeof(kill_cmd), "kill %d", pid);
                    my_zlog_info("检测到 go_video 进程 %d 已在运行，尝试终止", pid);
                    if (system(kill_cmd) != 0)
                    {
                        my_zlog_warn("无法终止 go_video 进程 %d", pid);
                        pclose(fp);
                        return NULL;
                    }
                    my_zlog_info("已终止 go_video 进程 %d", pid);
                }
            }
            pclose(fp);
        }

        // 进程未运行，启动它
        my_zlog_info("启动 go_video 程序并跳过浏览器");
        int res=system("sudo -u orangepi nohup /home/orangepi/go_video/go_video > /dev/null 2>&1 &");
        if(res!=0){
            my_zlog_error("启动 go_video 失败");
        }
        return NULL;
    }

    /* libdatachannel 原生推流与 Chromium 互斥；失败时 runtime_deps 回退浏览器 */
    while (1) {
        if (webrtcpush_should_use_mpp()) {
            my_zlog_info("WEBRTCPUSH: libdatachannel native push mode");
            {
                int pkill_rc = system("pkill chromium");
                if (pkill_rc == -1)
                    my_zlog_warn("pkill chromium: system() failed");
            }
            delay_s(2);
            while (s_webrtc_index == 1 && webrtcpush_should_use_mpp()) {
                if (webrtcpush_is_running()) {
                    delay_ms(200);
                    continue;
                }
                my_zlog_info("webrtcpush: starting native WebRTC push");
                webrtcpush_run_blocking();
                if (!webrtcpush_should_use_mpp()) {
                    my_zlog_warn("webrtcpush failed, switching to Chromium");
                    break;
                }
                delay_s(5);
            }
            if (!webrtcpush_should_use_mpp())
                run_chromium_cam_loop();
        } else {
            run_chromium_cam_loop();
        }
        delay_ms(500);
    }

    return NULL;
}

// 打开游览器线程，让游览器一直在一个线程中打开并运行
//  void *thread_open_browser(void *arg) {

//     if(g_device_type==DEVICE_PG_GPS0403){
//          return NULL;
//     }

//     int result = system("pkill  chromium");
//     if (result != 0) {
//         my_zlog_error("system error");
//     }
//     delay_s(5);
//     while(1){

//         if(s_webrtc_index==1) {
//             if(is_browser_running() == true ) {
//                 continue;
//             }else{
//                 my_zlog_info("open cam");
//                 opencamsh();//10s后打开游览器并且进入网址
//             }

//         }
//         delay_ms(200);
//     }

//     return NULL;
// }

// mqtt异常处理，断开自动重连，简单粗暴
void *thread_mqtt_reconnect(void *arg)
{
    int retry_count = 0;
    int rc = mqtt_init();

    while (rc != 0 && retry_count < MQTT_INIT_RETRY_MAX)
    {
        retry_count++;
        my_zlog_warn("wait... mqtt reconect,retry:%d/%d", retry_count, MQTT_INIT_RETRY_MAX);
        delay_ms(300);
        rc = mqtt_retry_failed_clients();
    }

    if (rc == 0)
    {
        s_mqtt_grc = 0;
        my_zlog_info("mqtt success");
    }
    else
    {
        s_mqtt_grc = 1;
        my_zlog_error("mqtt init failed after %d retries", MQTT_INIT_RETRY_MAX);
        send_fail_mqtt_conect();
    }

    mqtt_cycle();
    return NULL;
}

// 专门用于计时的线程
void *thread_time_calculation(void *arg)
{
    while (1)
    {

        device_fast_read(); // 用于快速判断设备的及时检查和停止

        delay_ms(5);

        g_device_delay_back_count++; // 设备计时，坦克打击倒退逻辑

        pthread_mutex_lock(&g_verify_mutex);
        g_verify_count++; // jwt验证计时,每15s一次
        pthread_mutex_unlock(&g_verify_mutex);

        if (g_verify_count >= 20000)
        { // 防止溢出
            pthread_mutex_lock(&g_verify_mutex);
            g_verify_count = 20000;
            pthread_mutex_unlock(&g_verify_mutex);
        }
        if (g_device_delay_back_count >= 5000)
            g_device_delay_back_count = 5000; // 防止溢出
    }
    return NULL;
}

// 专门处理MP3播放
void *thread_play_mp3(void *arg)
{
    audioplay_cycle();
    return NULL;
}

// 方向盘控制线程：25ms周期调用平滑处理，无匹配设备时自动退出
void *thread_steering_control(void *arg)
{
    my_zlog_info("steering_pthread");
    while(1) {
        if (!steering_control_process()) {
            break;
        }
        delay_ms(25);
    }
    return NULL;
}

// 等待线程结束
void thread_end_close()
{
    for (int i = 0; i < PTHREAD_MAX; i++)
    {
        if (s_thread[i])
            pthread_join(s_thread[i], NULL);
    }
}
