#include "mqtt_infor_handle.h"
#include "mqtt_common.h"
#include "common.h"
#include "app_device_common.h"
#include "drivers_common.h"
#include "modules_common.h"
#include "webrtcpush_run.h"

int g_heartbeat_count = 0; // 心跳计数

/*
 *
 */
pthread_mutex_t g_exit_count_mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
int g_devcontrol_exit_count = 0;

static int s_message_type = 0; // 接收的mqtt的s_message_type

static int s_valt[4]; // 存放mqtt接收的tpye，mode等

// 心跳发送格式*5/2
void heartbeat_send()
{

    static double voltage;
    static double current;
    voltage = ads1115_read_channel(0) * 5 / 2;
    current = ads1115_read_channel(1) * 5 / 2;
    current = (current - voltage) * 10;
    my_zlog_debug("v:%.2f", voltage);
    my_zlog_debug("i:%.2f", current);

    char voltage_str[20]; // 足够存储转换后的字符串的缓冲区
    sprintf(voltage_str, "%.2f", voltage);
    char current_str[20]; // 足够存储转换后的字符串的缓冲区
    sprintf(current_str, "%.2f", current);

    if (g_devcontrol_exit_count > 5)
        alarm_control(voltage); // 判断电压警报,在不动时候才判断

    /*读取程序版本号*/
    char *version_num = program_version();

    if (heat_tem() != 0)
    { // 获取CPU温度
        my_zlog_debug("获取cpu温度失败");
    }
    ipaddr_obtain(); // 获取ip
    int message = 1;

    cJSON *root = cJSON_CreateObject();
    cJSON *body = cJSON_CreateObject();
    cJSON *head = cJSON_CreateObject();

    cJSON_AddStringToObject(body, "ip", g_ip_address);                // 发送设备ip
    cJSON_AddStringToObject(body, "ID", mqtt_topic_app2dev_number()); // 发送设备号
    cJSON_AddStringToObject(body, "V", voltage_str);                  // 心跳发送电压
    cJSON_AddStringToObject(body, "I", current_str);                  // 心跳发送电流
    cJSON_AddStringToObject(body, "Tem", g_temperature);              // 发送温度
    cJSON_AddStringToObject(body, "version", version_num);            // 版本号

    cJSON_AddNumberToObject(head, "message_type", message);

    cJSON_AddItemToObject(root, "body", body);
    cJSON_AddItemToObject(root, "head", head);

    char *payload = cJSON_PrintUnformatted(root);

    my_zlog_debug("%s", payload);
    mqtt_publish_to_topics(mqtt_topic_dev2app_number(), mqtt_topic_pure_number(), payload, 0);

    free(payload);
    cJSON_Delete(root);
}

// 角度发送
void angle_mqtt_send()
{
    static int angle_i = 0;
    cJSON *root = cJSON_CreateObject();
    char TOPIC_send_angle[26];
    static double prev_angle = 0;
    static double rounded_angle;
    rounded_angle = low_pass_filter_360(prev_angle, tank_angle(), 0.7);
    sprintf(TOPIC_send_angle, "dev_rtinfo/%s", mqtt_topic_pure_number());
    cJSON_AddStringToObject(root, "type", "tank_angle");
    if (rounded_angle > 160 && rounded_angle < 180)
    {
        rounded_angle = 160;
    }
    else if (rounded_angle < 200 && rounded_angle > 180)
    {
        rounded_angle = 200;
    }
    cJSON_AddNumberToObject(root, "angle", rounded_angle);
    char *payload = cJSON_PrintUnformatted(root);
    angle_i++;
    if (angle_i >= 10)
    {
        my_zlog_debug("%s", payload);
        prev_angle = tank_angle();
        angle_i = 0;
    }
    if (fabs(rounded_angle) < 1e-8)
    {
        free(payload);
        cJSON_Delete(root);
        return;
    }
    mqtt_publish_to_all(TOPIC_send_angle, payload, 0);

    free(payload);
    cJSON_Delete(root);
}

// 心跳格式，每5s一次心跳
void mqtt_beat_wirte()
{

    if (g_heartbeat_count >= 30)
    {
        heartbeat_send();
        g_heartbeat_count = 0;
    }

    if (get_tank_angle_count() > 2)
    {
        switch (g_device_type)
        {
        case DEVICE_TANK0202:
        case DEVICE_TANK0203:
        case DEVICE_TANK0204:
            angle_mqtt_send();
            break;
        default:
            break;
        }
        set_tank_angle_count_clear();
    }
}

// message_type为3，控制pwm
void message_3(cJSON *body)
{
    cJSON *pwm_ctrl = cJSON_GetObjectItem(body, "pwm_ctrl");
    cJSON *pin_setctrl = cJSON_GetObjectItem(body, "pin_setctrl");
    if (pwm_ctrl == NULL || pin_setctrl == NULL)
    {
        return;
    }
    cJSON *mode = cJSON_GetObjectItem(pwm_ctrl, "mode"); // mode=1 速度，mode=2 转向(unsigned char)
    cJSON *type = cJSON_GetObjectItem(pwm_ctrl, "type");
    cJSON *val = cJSON_GetObjectItem(pwm_ctrl, "val"); // val为pwm的值 0~100(unsigned char)(unsigned char)

    int modeTemp = mode->valueint;
    int typeTemp = type->valueint;
    int valTemp = val->valueint;

    s_valt[0] = typeTemp;
    s_valt[1] = modeTemp;
    s_valt[2] = valTemp;

    my_zlog_debug("typeTemp:%d", s_valt[0]);
    my_zlog_debug("modeTemp:%d", s_valt[1]);
    my_zlog_debug("valTemp:%d", s_valt[2]);

    device_walk_control(g_device_type, s_valt);
}

void message_4(cJSON *body)
{ // message 为4时候

    cJSON *pwm_ctrl = cJSON_GetObjectItem(body, "pwm_ctrl");
    cJSON *pin_setctrl = cJSON_GetObjectItem(body, "pin_setctrl");
    if (pwm_ctrl == NULL || pin_setctrl == NULL)
    {
        return;
    }
    cJSON *pin = cJSON_GetObjectItem(pin_setctrl, "pin");
    cJSON *val = cJSON_GetObjectItem(pin_setctrl, "val"); // val为pwm的值 0~100(unsigned char)(unsigned char)

    int pinTemp = pin->valueint;
    int valTemp = val->valueint;

    if (valTemp >= 1)
    {
        valTemp = 1;
    }

    s_valt[0] = 0;
    s_valt[1] = pinTemp;
    s_valt[2] = valTemp;

    my_zlog_debug("pinTemp:%d", s_valt[1]);
    my_zlog_debug("valTemp:%d", s_valt[2]);

    device_gpio_control(g_device_type, s_valt[1], s_valt[2]);

    if (g_device_type != DEVICE_CAR0102) {
        tank_shot_stop_control(g_device_type, s_valt[1], s_valt[2]);
    }
}

// 当接收到2时候验证
static void refresh_cam_browser_only(const char *reason)
{
    if (webrtcpush_should_use_mpp() && webrtcpush_is_running()) {
        my_zlog_info("refresh_cam skipped (webrtcpush): %s", reason ? reason : "no browser");
        return;
    }
    refresh_cam();
}

void message_2_judyverify(cJSON *body)
{
    if (VERIFIED_MODE == FALSE)
    {
        refresh_cam_browser_only("MQTT type2 verify off");
        my_zlog_warn("不使用验证");
        return;
    }

    receive_jwt(body);
    if (g_verify_index == 0)
    {
        refresh_cam_browser_only("MQTT type2 JWT verify ok");
    }
    else
    {
        my_zlog_warn("验证不通过");
    }
}

// 当接收到3时候验证
void message_3_judyverify(cJSON *body)
{
    if (VERIFIED_MODE == FALSE)
    {
        message_3(body);
        my_zlog_warn("不使用验证");
        return;
    }

    receive_jwt(body);
    if (g_verify_index == 0)
    {
        message_3(body);
    }
    else
    {
        my_zlog_warn("验证不通过");
    }
}

// 当接收到4时候验证
void message_4_judyverify(cJSON *body)
{
    if (VERIFIED_MODE == FALSE)
    {
        message_4(body);     
        my_zlog_warn("不使用验证");
        return;
    }

    receive_jwt(body);
    if (g_verify_index == 0)
    {
        message_4(body);
    }
    else
    {
        my_zlog_warn("验证不通过");
    }
}


void message_6_steering_judyverify(cJSON *body)
{
    if (VERIFIED_MODE == FALSE)
    {
        steering_mqtt_recv(body);
        my_zlog_warn("不使用验证");
        return;
    }

        receive_jwt(body);
    if (g_verify_index == 0)
    {
        steering_mqtt_recv(body);
    }
    else
    {
        my_zlog_warn("验证不通过");
    }
}

void message_7_joystick_judyverify(cJSON *body)
{
    cJSON *joystick_ctrl = cJSON_GetObjectItem(body, "joystick_ctrl");
    if (!cJSON_IsObject(joystick_ctrl))
    {
        my_zlog_warn("joystick_ctrl invalid");
        return;
    }

    if (VERIFIED_MODE == FALSE)
    {
        ptz_driver_set_joystick_json(joystick_ctrl);
        my_zlog_warn("不使用验证");
        return;
    }

    receive_jwt(body);
    if (g_verify_index == 0)
    {
        ptz_driver_set_joystick_json(joystick_ctrl);
    }
    else
    {
        my_zlog_warn("验证不通过");
    }
}

// 接收到设备改名函数
int device_mqttchange_name(cJSON *device_id)
{
    cJSON *id = cJSON_GetObjectItem(device_id, "id");     // 提取ID
    cJSON *date = cJSON_GetObjectItem(device_id, "date"); // 提取日期
    char *device_change_id = id->valuestring;
    char *device_change_date = date->valuestring;
    device_changename_back(device_change_date, device_change_id);
    // 输出提取的数据
    my_zlog_info("设备ID: %s", device_change_id);
    my_zlog_info("日期: %s", device_change_date);

    return 0;
}

int device_message_receive(cJSON *json)
{ // 接收到的控制设备的mqtt消息

    cJSON *head = cJSON_GetObjectItem(json, "head");
    cJSON *message_type = cJSON_GetObjectItem(head, "message_type");

    if (cJSON_IsObject(head) && cJSON_IsNumber(message_type))
    {

        cJSON *body = cJSON_GetObjectItem(json, "body"); // 提取 body数据段

        pthread_mutex_lock(&g_exit_count_mutex);
        g_devcontrol_exit_count = 0;
        pthread_mutex_unlock(&g_exit_count_mutex);

        s_message_type = message_type->valueint;
        my_zlog_debug("message_type: %d", message_type->valueint);

        if (s_message_type == 2013) {
            if (message2013_recverigy_open(body) == 0) {
                my_zlog_debug("进入是否需要验证");
                return 0;
            }
            return 1;
        }

        if (!cJSON_IsObject(body))
        {
            return 1;
        }

        switch (s_message_type)
        {
        case 2:
            message_2_judyverify(body);
            my_zlog_debug("进入刷新");
            break;
        case 3:
            message_3_judyverify(body);
            set_self_control_index(false);
            my_zlog_debug("进入pwm控制");
            break;
        case 4:
            message_4_judyverify(body);
            set_self_control_index(false);
            my_zlog_debug("进入引脚控制");
            break;
        case 5:
            audio_wheat_init();
            audio_speaker_init();
            my_zlog_debug("执行麦和喇叭命令");
            break;
        case 6:
            message_6_steering_judyverify(body);
            my_zlog_debug("执行方向盘命令");
            break;
        case 7:
            message_7_joystick_judyverify(body);
            my_zlog_debug("执行手机轮盘命令");
            break;
        case 2001:
            audioplay_mqtt_receive(body);
            my_zlog_debug("进入音频播放");
            break;
        case 2002:
            device_mqttchange_name(body);
            my_zlog_debug("进入修改设备号");
            break;
        case 2003:
            scan_wifi_json();
            my_zlog_debug("进入查询WiFi");
            break;
        case 2004:
            // wifi_change_recmqtt(body);
            my_zlog_debug("进入修改WiFi");
            break;
        case 2006:
            message2006_verify(body);
            my_zlog_debug("进入消息为2006验证");
            break;
        case 2007:
            device_send_saved_wifi();
            my_zlog_debug("查询已保存wifi和现在已连接WiFi");
            break;
        case 2008:
            device_wifi_rec_sava(body);
            my_zlog_debug("保存wifi");
            break;
        case 2009:
            device_wifi_rec_delete(body);
            my_zlog_debug("删除已保存wifi");
            break;
        case 2011:
            {
                int res = system("sudo reboot");
                if (res == 0)
                    my_zlog_info("重启成功");
            }
            break;
        case 2012:
            refresh_cam();
            my_zlog_debug("刷新成功");
            break;
        case 2016:
            mqtt_verify_data_clear(body);
            my_zlog_debug("清除验证数据");
            break;
        case 2017:
            audioplay_local_mqtt_receive(body);
            my_zlog_debug("有人驾驶本地音频");
            break;
        case 2025:
            receive_self_contorl_mqtt(body);
            my_zlog_debug("device self comtrol");
            break;
        case 2026:
            receive_self_contorl_date_mqtt(body);
            my_zlog_debug("device self comtrol date save");
            break;
        case 2027:
            mqtt_audio_tts(body);
            my_zlog_debug("device audio_tts");
            break;
        case 2028:
            tailscale_control(body);
            my_zlog_debug("tailscale control");
            break;
        default:
            break;
        }
    }
    else
        return 3;

    return 0;
}
