#include "evse_manager.h"
#include "evse_state.h"
#include "evse_error.h"
#include "evse_hardware.h"
#include "evse_config.h"
#include "evse_api.h"
#include "auth.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include <string.h>

static const char *TAG = "EVSE_Manager";

static TickType_t auth_expiration = 0;

static SemaphoreHandle_t evse_mutex;
static QueueHandle_t auth_event_queue = NULL;

#define EVSE_MANAGER_TICK_PERIOD_MS 1000  // 1 segundo

// ===== Task de ciclo principal =====
static void evse_manager_task(void *arg) {
    while (true) {
        evse_manager_tick();
        vTaskDelay(pdMS_TO_TICKS(EVSE_MANAGER_TICK_PERIOD_MS));
    }
}

static void evse_auth_event_task(void *arg) {
    auth_event_t evt;

    while (true) {
        if (xQueueReceive(auth_event_queue, &evt, portMAX_DELAY)) {
            ESP_LOGI(TAG, "Evento de autenticação recebido: %s (%s)",
                     evt.tag, evt.authorized ? "AUTORIZADO" : "NEGADO");

            if (evt.authorized) {
                evse_authorize();
                auth_expiration = xTaskGetTickCount() + pdMS_TO_TICKS(2 * 60 * 1000); // 2 minutos
            } else {
                evse_manager_set_authorized(false);
                ESP_LOGW(TAG, "Tag inválida, carregamento negado.");
            }
        }
    }
}


// ===== Inicialização dos módulos do EVSE =====
void evse_manager_init(void) {
    evse_mutex = xSemaphoreCreateMutex();

    evse_config_init();
    evse_error_init();
    evse_hardware_init();
    evse_state_init();

    ESP_LOGI(TAG, "EVSE Manager inicializado.");

    xTaskCreate(evse_manager_task, "evse_manager_task", 4096, NULL, 5, NULL);
}

// ===== Inicia processamento de eventos de autenticação =====
void evse_manager_start(QueueHandle_t queue) {
    auth_event_queue = queue;
    xTaskCreate(evse_auth_event_task, "evse_auth_evt", 4096, NULL, 5, NULL);
}

void evse_manager_tick(void) {
    xSemaphoreTake(evse_mutex, portMAX_DELAY);

    evse_hardware_tick();
    evse_error_tick();
    evse_state_tick();
    evse_temperature_check();

    // Verifica expiração de autorização somente se auth está habilitado
    if (auth_is_enabled()) {
        if (evse_state_get_authorized() && auth_expiration > 0 &&
            xTaskGetTickCount() >= auth_expiration) {
            ESP_LOGI(TAG, "Autorização expirada após 2 minutos.");
            evse_state_set_authorized(false);
            auth_expiration = 0;
        }
    } else {
        // Se autenticação não é necessária, sempre considera autorizado
        if (!evse_state_get_authorized()) {
            evse_state_set_authorized(true);
            ESP_LOGI(TAG, "Autenticação desativada: autorização forçada.");
        }
    }


    xSemaphoreGive(evse_mutex);
}

// ===== Controles e status =====
bool evse_manager_is_available(void) {
    return evse_config_is_available();
}

void evse_manager_set_available(bool available) {
    evse_config_set_available(available);
}

void evse_manager_set_authorized(bool authorized) {
    evse_state_set_authorized(authorized);
}

bool evse_manager_is_charging(void) {
    return evse_state_is_charging(evse_get_state());
}

void evse_manager_set_enabled(bool enabled) {
    evse_config_set_enabled(enabled);
}

bool evse_manager_is_enabled(void) {
    return evse_config_is_enabled();
}
