#include "common.h"
#include "self_devicecontrol.h"
#include "modules_common.h"
#include "app_device_common.h"
#include "drivers_common.h"


static ThreadPool_t *g_self_devicecontrol_task_t;//自控任务线程函数

static bool g_self_device_control_switch_index=false;//自控开关。是否打开或者关闭

static int g_self_control_interval=0;

static int g_self_control_time_count=0;
static pthread_mutex_t g_self_control_time_count_mutex = PTHREAD_MUTEX_INITIALIZER;

static devicecontroltask_t *g_self_device_control_date=NULL;//设备自控全局数据指针
static pthread_mutex_t g_self_device_control_date_mutex = PTHREAD_MUTEX_INITIALIZER;

static device_automatic_date_t g_automatic_date_t[DEVICE_WALK_SIGN_MAX]={0};

/*
* @brief 释放内存
*/
void free_device_tasks_memory() { 
    if(g_self_device_control_date!=NULL){
        pthread_mutex_lock(&g_self_device_control_date_mutex);
        free(g_self_device_control_date);
        g_self_device_control_date=NULL;
        my_zlog_info("free g_self_device_control_date");
        pthread_mutex_unlock(&g_self_device_control_date_mutex);
    } else return;  
   
}

/*
* @brief 分配内存封装函数
*/
void malloc_device_tasks_memory() {
    pthread_mutex_lock(&g_self_device_control_date_mutex);
    if(g_self_device_control_date==NULL){
        g_self_device_control_date=(devicecontroltask_t*)malloc(sizeof(devicecontroltask_t));
        memset(g_self_device_control_date, 0, sizeof(devicecontroltask_t)); // 清零内存 
        my_zlog_info("malloc g_self_device_control_date");
    }
   pthread_mutex_unlock(&g_self_device_control_date_mutex);
}

/*
* @brief 自控线程中的计时函数接口,每20ms加一次
* @param[in] self_control_time_count，计时次数
*/
void set_self_control_time_countfuntion(){
    pthread_mutex_lock(&g_self_control_time_count_mutex);
    g_self_control_time_count++;
    if(g_self_control_time_count>30000) g_self_control_time_count=30001;
    pthread_mutex_unlock(&g_self_control_time_count_mutex);
}


/*
* @brief 自控线程中的任务
*/
void self_device_control_task(){
    static int i=0;

    static unsigned char valt[3];

    int time_now = g_self_control_time_count*20;


    if(i>g_self_device_control_date->id_run_count){
            
            if(g_self_control_interval>time_now){
                return;
            }

            pthread_mutex_lock(&g_self_control_time_count_mutex);
            g_self_control_time_count=0;//将计时重置
            pthread_mutex_unlock(&g_self_control_time_count_mutex);
            i=0;
    }
    time_now = g_self_control_time_count*20;

    if(time_now > g_self_device_control_date->run_cool[i]&&
        time_now <= (g_self_device_control_date->run_cool[i]+g_self_device_control_date->timed_run[i]))
    {
        for(int j=0;j<g_automatic_date_t[g_self_device_control_date->id_run[i]].action_count;j++){

            valt[1]=g_automatic_date_t[g_self_device_control_date->id_run[i]].mode[j];
            valt[2]=g_automatic_date_t[g_self_device_control_date->id_run[i]].val[j];
        
            if(valt[2]>2) device_walk_control(g_device_type,valt);
            else if(valt[2]<=2) device_gpio_control(g_device_type,valt[1],valt[2]);

        }


    }else if(time_now >
            (g_self_device_control_date->run_cool[i]+g_self_device_control_date->timed_run[i]))
    {
    
        device_stop(g_device_type);//停止

        pthread_mutex_lock(&g_self_control_time_count_mutex);
        g_self_control_time_count=0;//将计时重置
        pthread_mutex_unlock(&g_self_control_time_count_mutex); 
        ++i;
    }
  
}

static bool g_selfcontrol_task_index_s=true;
/*
* @brief 自控线程
*/
void self_device_control_task_function(){
    my_zlog_info("自控线程池循环开始");
    static int s_status =0; 
    while(g_selfcontrol_task_index_s){
        if(g_self_device_control_switch_index==true){
            self_device_control_task();
            s_status=1;
        }else if(g_self_device_control_switch_index==false){
            if(s_status==1) {
                device_stop(g_device_type);
                s_status=0;
            }
            delay_ms(100);
        }
    }
    free_device_tasks_memory();
    my_zlog_info("自控线程池循环终止");
    return ;
}

/*
* @brief 开启自控线程
*/
void self_device_pthrpoll_task_init(){

	g_self_devicecontrol_task_t=thread_pool_init(1,1);
	thread_pool_add_task(g_self_devicecontrol_task_t, self_device_control_task_function, NULL);
	my_zlog_info("自控线程池打开");
}

/*
* @brief 自控的线程开启标识设置。
* @param[in]  当index为，true为开，false为关
*/
void set_self_control_index(bool index){    
    g_self_device_control_switch_index =index;
}

/*
* @brief 获取自控的线程开启标识。
*/
bool get_self_control_index(){
    return g_self_device_control_switch_index;
}

/*
* @brief 销毁自控的线程
*/
void self_control_thread_close(){
    if(get_self_control_index()==true){
        my_zlog_info("Destroy the thread of the automatic control device");
        g_selfcontrol_task_index_s=false;
	    thread_pool_destroy(g_self_devicecontrol_task_t);
        return ;
    }
    my_zlog_info("The thread of the automatic control device is not opened");
}

/*
* @brief 返回MQTT自控打开或者关闭的函数 
*/
void send_self_contorl_mqtt(){
    // 创建根对象
    cJSON *root = cJSON_CreateObject();
    
    // 创建head对象
    cJSON *head = cJSON_CreateObject();
    cJSON_AddNumberToObject(head, "message_type", 3018);
    cJSON_AddItemToObject(root, "head", head);
    
    // 创建body对象
    cJSON *body = cJSON_CreateObject();
    cJSON_AddStringToObject(body, "cmd", "device_mycontrol");
    cJSON_AddNumberToObject(body, "switch_reply_status", get_self_control_index());
    cJSON_AddItemToObject(root, "body", body);
    
    // 将cJSON对象转换为字符串
    char *json_str = cJSON_PrintUnformatted(root);

    my_zlog_info("%s",json_str);

    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(json_str), json_str, 0, false); 
    } 

    cJSON_Delete(root);  // 释放 cJSON 对象
}

/*
* @brief MQTT发送自控的相关的动作控制消息的函数，找后端要动作组合
*/
void send_self_contorl_date_mqtt(){
        // 创建根对象
    cJSON *root = cJSON_CreateObject();
    
    // 创建head对象
    cJSON *head = cJSON_CreateObject();
    cJSON_AddNumberToObject(head, "message_type", 3019);
    cJSON_AddItemToObject(root, "head", head);
    
    // 创建body对象
    cJSON *body = cJSON_CreateObject();
    cJSON_AddStringToObject(body, "cmd", "device_control_demand_date");
    cJSON_AddNumberToObject(body, "status", 1);
    cJSON_AddItemToObject(root, "body", body);
    
    // 将cJSON对象转换为字符串
    char *json_str = cJSON_PrintUnformatted(root);

    my_zlog_info("%s",json_str);

    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
        mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(json_str), json_str, 0, false); 
    } 

    cJSON_Delete(root);  // 释放 cJSON 对象
}


/*
* @brief MQTT接收自控消息的函数 
*/
void receive_self_contorl_mqtt(cJSON *body){

    if (!body) {
        my_zlog_error("JSON error!");
        return;
    }

    cJSON *switch_status = cJSON_GetObjectItem(body, "switch_status");

    if (switch_status == NULL || !cJSON_IsNumber(switch_status)) {
    my_zlog_error("Invalid switch_status!");
    return;
    }

    static int s_switch_status = 0;
    static bool s_thread_index=0;
    s_switch_status=switch_status->valueint;

    if(s_switch_status == DEVICE_SELF_CONTROL_OPEN){
       if(s_thread_index==0) {
        self_device_pthrpoll_task_init();
        malloc_device_tasks_memory();//分配内存
       }

       pthread_mutex_lock(&g_self_control_time_count_mutex);
       g_self_control_time_count=0;
       pthread_mutex_unlock(&g_self_control_time_count_mutex);

       g_self_device_control_switch_index =true;
       s_thread_index=1;
       my_zlog_info("open device auto");
    }else if(s_switch_status == DEVICE_SELF_CONTROL_CLOSE) {
       g_self_device_control_switch_index =false;
       my_zlog_info("close device auto");
       return ;
    }

    cJSON *interval=cJSON_GetObjectItem(body, "interval");
    g_self_control_interval=interval->valueint;


    // 2️ id_run 数组
    cJSON *id_run = cJSON_GetObjectItem(body, "id_run");

    pthread_mutex_lock(&g_self_device_control_date_mutex);//加锁

    g_self_device_control_date->id_run_count = 0;
    if (cJSON_IsArray(id_run)) {
        int size = cJSON_GetArraySize(id_run);
        for (int i = 0; i < size && i < DEVICE_WALK_SIGN_MAX; i++) {
            cJSON *item = cJSON_GetArrayItem(id_run, i);
            g_self_device_control_date->id_run[i] = item->valueint;
            g_self_device_control_date->id_run_count=i;
        }
    }

     // 3 run_cool 数组
    cJSON *run_cool = cJSON_GetObjectItem(body, "run_cool");
    if (cJSON_IsArray(run_cool)) {
        int size = cJSON_GetArraySize(run_cool);
        for (int i = 0; i < size&& i < DEVICE_WALK_SIGN_MAX ; i++) {
            cJSON *item = cJSON_GetArrayItem(run_cool, i);
            g_self_device_control_date->run_cool[i] = item->valueint;
        }
    }

      // 4 timed_run 数组
    cJSON *timed_run = cJSON_GetObjectItem(body, "timed_run");
    if (cJSON_IsArray(timed_run)) {
        int size = cJSON_GetArraySize(timed_run);
        for (int i = 0; i < size && i < DEVICE_WALK_SIGN_MAX ; i++) {
            cJSON *item = cJSON_GetArrayItem(timed_run, i);
            g_self_device_control_date->timed_run[i] = item->valueint;
        }
    }

    pthread_mutex_unlock(&g_self_device_control_date_mutex);//解锁

    send_self_contorl_mqtt();

    my_zlog_info("count:%d",g_self_device_control_date->id_run_count);

    return;
}

/*
* @brief MQTT接收自控的相关的动作控制消息的函数，接收后端相应动作组合
*/
void receive_self_contorl_date_mqtt(cJSON *body){
    if (!body) {
        my_zlog_error("JSON error!");
        return;
    }

    static int s_action_id = 0;

    cJSON *switch_status = cJSON_GetObjectItem(body, "switch_status");
    if(switch_status==NULL) return;
    static int s_switch_status = 0;
    s_switch_status=switch_status->valueint;


    if(s_switch_status == 1){
        cJSON *config= cJSON_GetObjectItem(body, "config");
        if(config==NULL)  return;
        if (cJSON_IsArray(config)) {
            int config_size = cJSON_GetArraySize(config);
            for (int i = 0; i < config_size && i < DEVICE_WALK_SIGN_MAX; i++) {

                cJSON *config_item = cJSON_GetArrayItem(config, i);
                cJSON *action_id = cJSON_GetObjectItemCaseSensitive(config_item, "action_id");

                s_action_id=action_id->valueint;


                cJSON *action_array = cJSON_GetObjectItemCaseSensitive(config_item, "action");
                if(cJSON_IsArray(action_array)){
                    int action_size = cJSON_GetArraySize(action_array);

                    for (int j = 0; j < action_size && j < DEVICE_WALK_SIGN_MAX; j++) {

                        cJSON *item = cJSON_GetArrayItem(action_array, j);

                        // 获取 combination 和 speed
                        cJSON *combination = cJSON_GetObjectItemCaseSensitive(item, "combination");
                        cJSON *speed = cJSON_GetObjectItemCaseSensitive(item, "speed");
                        g_automatic_date_t[s_action_id].mode[j]=combination->valueint;
                        g_automatic_date_t[s_action_id].val[j]=speed->valueint;

                        g_automatic_date_t[s_action_id].action_count++;

                       my_zlog_info("combination:%d",g_automatic_date_t[s_action_id].mode[j]);
                       my_zlog_info("speed:%d",g_automatic_date_t[s_action_id].val[j]);
                  
                    }
                }     
                
            }
        }
        
    }else if(s_switch_status == 0){
        memset(g_automatic_date_t[s_action_id].mode, 0, sizeof(g_automatic_date_t[s_action_id].mode));
        memset(g_automatic_date_t[s_action_id].val, 0, sizeof(g_automatic_date_t[s_action_id].val));
    }

    my_zlog_info("action_count:%d",g_automatic_date_t[s_action_id].action_count);

    return;

}


/*
* @brief 开机需要进行配置自控相关的初始化
*/
int get_device_self_control_configuration_initialization(){
    static bool index=0;
    if(index == 0){
        send_self_contorl_date_mqtt();
        index = 1;
        return 0;
    }else return -1; 
}