#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"

int g_heartbeat_count=0;//心跳计数

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

int g_message_type=0;//接收的mqtt的g_message_type

static unsigned char g_valt[4];//存放mqtt接收的tpye，mode等

//心跳发送格式*5/2
void heartbeat_send() {
    float voltage = ina226_readbusvoltage();
    float current = ina226_readcurrent();
    my_zlog_debug("ina226_v:%.2f", voltage);
    if(voltage<=0.5){
        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);
    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_dev2app_number(), strlen(payload), payload, 0, false); 
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(payload), payload, 0, false); 
    }
    
    cJSON_Delete(root);  // 释放 cJSON 对象
}

//角度发送
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.6);
    sprintf(TOPIC_send_angle,"dev_rtinfo/%s",mqtt_topic_pure_number());
    cJSON_AddStringToObject(root, "type","tank_angle");
    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(rounded_angle == 0){
        cJSON_Delete(root);
        return;
    }
    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, TOPIC_send_angle, strlen(payload), payload, 0, false); 
    }
    
    cJSON_Delete(root);  // 释放 cJSON 对象  
}

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

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

    
    switch (g_device_type) {
        case DEVICE_TANK0202:
        case DEVICE_TANK0203:
        case DEVICE_TANK0204:
            angle_mqtt_send();
            break;
        default:
            break;
        }
  
}

//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)

    unsigned char modeTemp= mode->valueint;
    unsigned char typeTemp=type->valueint;
    unsigned char valTemp= val->valueint;

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

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

    device_walk_control(g_device_type,g_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)
    
    unsigned char pinTemp =pin->valueint;
    unsigned char valTemp = val->valueint;

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

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

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

    device_gpio_control(g_device_type,g_valt[1],g_valt[2]);
    
    tank_shot_stop_control(g_device_type,g_valt[1],g_valt[2]);
}

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

    receive_jwt(body);
   if(g_verify_index == 0) {
    refresh_cam();   
   } 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("验证不通过");
   }
}


//接收到设备改名函数
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_debug("设备ID: %s", device_change_id);
    my_zlog_debug("日期: %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数据段
        if (!cJSON_IsObject(body)) {
            return 1;
        }

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

        g_message_type=message_type->valueint;
        my_zlog_debug("message_type: %d",message_type->valueint);
        switch(g_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 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_debug("重启成功");
                break;
            case 2012:
                refresh_cam();    
                my_zlog_debug("刷新成功");
                break;
            case 2013:
                message2013_recverigy_open(body);
                my_zlog_debug("进入是否需要验证");
                break;
            case 2014:
                control_pthread_function("open");
                my_zlog_debug("打开控制台推送");
                break;
            case 2015:
                control_pthread_function("close");
                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_info("device self comtrol date save");
            case 2027:
                mqtt_audio_tts(body);
                my_zlog_info("device audio_tts");
            default:
                break;
        }
    }else return 3;     
 
    return 0;
}
