// ihm_gateway.c
#include "ihm_gateway.h"
#include "ihm.h"
#include <stdio.h>
#include <stdlib.h>
#include "platform_detect.h"
#include "cJSON.h"
#include "esp_log.h"
#include "washingMachineState.h"

static const char *TAG = "IHM_GW";


static QueueHandle_t xIHMEventQueue = NULL;

QueueHandle_t getIHMQueueHandle(void) {
    return xIHMEventQueue;
}

void ihm_gateway_init(void) {
    if (!xIHMEventQueue) {
        xIHMEventQueue = xQueueCreate(32, sizeof(xIHMEvent_t *));
    }
}

void ihm_gateway_post_event(xIHMEvent_t *evt) {
    if (!xIHMEventQueue) return;

    if (platform_is_pc()) {
        xQueueSend(xIHMEventQueue, &evt, 0); // non bloquant sur PC
    } else {
        xQueueSend(xIHMEventQueue, &evt, portMAX_DELAY); // bloquant ESP32
    }
}

extern lv_subject_t wifiStatus;

void ihm_gateway_process_queue(void) {
    if (!xIHMEventQueue) return;

    xIHMEvent_t *evt = NULL;

#if CONFIG_IDF_TARGET_LINUX
        while (xQueueReceive(xIHMEventQueue, &evt,  pdMS_TO_TICKS(0)) == pdTRUE)
#else
        while (xQueueReceive(xIHMEventQueue, &evt,  pdMS_TO_TICKS(10)) == pdTRUE)
#endif
    {
    if (!evt) return;

    UBaseType_t pending = uxQueueMessagesWaiting(xIHMEventQueue);
    ESP_LOGE(TAG,"Evt recu %d. La queue comporte %d éléments à traiter", evt->eEventType, pending);
    
    lv_async_call(traiteEvt, evt);
    }
}

void traiteEvt(void *arg)
{
      xIHMEvent_t *evt = (xIHMEvent_t *)arg;
    switch (evt->eEventType)
    {
    case IHM_EVT_WIFI_STATUS:
        lv_subject_set_int(&wifiStatus, *(bool *)evt->pvData);
        break;

    case IHM_EVT_TIME_SETTED:
        draw_time(evt->pvData);
         break;

    case IHM_EVT_OTA_STARTED:
        app_ota_display();
        break;

    case IHM_EVT_HUMID_TEMP:
        draw_temp((char *)evt->pvData);
        break;

    case IHM_EVT_TEMP_RECUE:
        draw_tempExt((char *)evt->pvData);
        break;

    case IHM_EVT_PUISSANCE_EMISE:
    {
        int val = *(int *)evt->pvData;
        // if(val == 0) lv_chart_set_next_value(myChart, ser, LV_CHART_POINT_NONE);
        // else lv_chart_set_next_value(myChart, ser, val);
        break;
    }

    case IHM_EVT_ETAT_MACHINE:
    {
        char *etatMachine = evt->pvData;
        WashingMachineState wms = traiteMessage(etatMachine);
        char etat[80];
        getEtatMachineStr(wms, etat,80);
        ESP_LOGE(TAG,"Etat machine : %s", etat);
        draw_minuteur(etat);
        // lv_label_set_text(lblEtatMachine, etatFormate);
        break;
    }

    case IHM_EVT_HAUTEUR_CUVE:
    {
        float hauteur = *(float *)evt->pvData;
        // lv_label_set_text_fmt(lblHauteurCuve, "%.0f cm", hauteur);
        break;
    }

    case IHM_EVT_METEO_RECUE:{
        //(void *)evt->pvData; // Pointeur sur tableau
        //(void *)evt->pvData
        ESP_LOGE(TAG, "Reception evt MF");

        // On ne veut liberer la memoire que lorsque l'evenement aura été traité!
        evt->bNeedToFreeData=false;
        meteo_event_payload_t *datas = (meteo_event_payload_t *) evt->pvData;
        for (size_t i = 0; i < 3; i++)
        {
            ESP_LOGE(TAG,"Type: %s - Valide : %d - %s", datas->daily[i].type, datas->daily[i].isValid, datas->daily[i].previsions.desc);
        }
        for (size_t i = 0; i < 3; i++)
        {
            ESP_LOGE(TAG,"Type: %s - Valide : %d - %s - %s - %f", datas->forecast[i].type, datas->forecast[i].isValid, datas->forecast[i].previsions.desc, datas->forecast[i].previsions.icon, datas->forecast[i].previsions.value);
        }
        
        draw_meteo(datas);
        //lv_subject_set_int(&meteoStatus, 0);
        //display_unlock("weather_data_retreived");
         ESP_LOGE(TAG, "Fin Reception evt MF");
        break;
    }

    default:
        ESP_LOGE(TAG, "Evt inconnu");
        break;
    }
    // Nettoyage mémoire sécurisé
    if (evt->bNeedToFreeData && evt->pvData){
        //ESP_LOGE(TAG, "Libération mémoire");
        free(evt->pvData);
    }
    free(evt);
    ESP_LOGV(TAG, "Evt traité");
}
