#include "dashboard_api.h"
#include "esp_log.h"
#include "cJSON.h"
#include "evse_api.h"
#include "evse_error.h"
#include "evse_config.h"
#include "evse_limits.h"


static const char *TAG = "dashboard_api";

static esp_err_t dashboard_get_handler(httpd_req_t *req) {
    httpd_resp_set_type(req, "application/json");

    // Cria o objeto JSON principal do dashboard
    cJSON *dashboard = cJSON_CreateObject();

    // Status do sistema
    evse_state_t state = evse_get_state();
    int runtime_current = evse_get_runtime_charging_current();
    int requested_current = evse_get_charging_current();
    int hardware_max = evse_get_max_charging_current();
    int power = runtime_current * 230;

    cJSON_AddStringToObject(dashboard, "status", evse_state_to_str(state));

    // Aliases de topo para clientes novos (mantendo compatibilidade com chargers[])
    cJSON_AddNumberToObject(dashboard, "currentA", runtime_current);
    cJSON_AddNumberToObject(dashboard, "currentLimitNowA", runtime_current);
    cJSON_AddNumberToObject(dashboard, "maxCurrentA", requested_current);
    cJSON_AddNumberToObject(dashboard, "hardwareMaxA", hardware_max);
    cJSON_AddNumberToObject(dashboard, "power", power);
    cJSON_AddNumberToObject(dashboard, "powerW", power);

    // Carregador - informação do carregador 1 (adapte conforme necessário)
    cJSON *chargers = cJSON_CreateArray();
    cJSON *charger1 = cJSON_CreateObject();
    cJSON_AddNumberToObject(charger1, "id", 1);
    cJSON_AddStringToObject(charger1, "status", evse_state_to_str(state));
    cJSON_AddNumberToObject(charger1, "current", runtime_current);
    cJSON_AddNumberToObject(charger1, "currentA", runtime_current);
    cJSON_AddNumberToObject(charger1, "maxCurrent", requested_current);
    cJSON_AddNumberToObject(charger1, "maxCurrentA", requested_current);

    // Calcular a potência com base na corrente (considerando 230V)
    cJSON_AddNumberToObject(charger1, "power", power);
    cJSON_AddNumberToObject(charger1, "powerW", power);

    cJSON_AddItemToArray(chargers, charger1);
    cJSON_AddItemToObject(dashboard, "chargers", chargers);

    // Consumo e tempo de carregamento
    cJSON_AddNumberToObject(dashboard, "energyConsumed", evse_get_consumption_limit());
    cJSON_AddNumberToObject(dashboard, "chargingTime", evse_get_charging_time_limit());

    // Alertas
    cJSON *alerts = cJSON_CreateArray();
    if (evse_is_limit_reached()) {
        cJSON_AddItemToArray(alerts, cJSON_CreateString("Limite de consumo atingido."));
    }
    if (!evse_config_is_available()) {
        cJSON_AddItemToArray(alerts, cJSON_CreateString("Estação indisponível."));
    }
    if (!evse_config_is_enabled()) {
        cJSON_AddItemToArray(alerts, cJSON_CreateString("EVSE desativado."));
    }
    cJSON_AddItemToObject(dashboard, "alerts", alerts);

    // Erros
    uint32_t error_bits = evse_get_error();
    cJSON *errors = cJSON_CreateArray();
    if (error_bits & EVSE_ERR_DIODE_SHORT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Diodo curto-circuitado"));
    if (error_bits & EVSE_ERR_LOCK_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no travamento"));
    if (error_bits & EVSE_ERR_UNLOCK_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no destravamento"));
    if (error_bits & EVSE_ERR_RCM_SELFTEST_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no autoteste do RCM"));
    if (error_bits & EVSE_ERR_RCM_TRIGGERED_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("RCM disparado"));
    if (error_bits & EVSE_ERR_TEMPERATURE_HIGH_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Temperatura elevada"));
    if (error_bits & EVSE_ERR_PILOT_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Erro no sinal piloto"));
    if (error_bits & EVSE_ERR_TEMPERATURE_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no sensor de temperatura"));
    cJSON_AddItemToObject(dashboard, "errors", errors);

    // Enviar resposta JSON
    const char *json_str = cJSON_Print(dashboard);
    httpd_resp_sendstr(req, json_str);

    // Liberar memória
    free((void *)json_str);
    cJSON_Delete(dashboard);

    return ESP_OK;
}

void register_dashboard_handlers(httpd_handle_t server, void *ctx) {
    httpd_uri_t uri = {
        .uri = "/api/v1/dashboard",
        .method = HTTP_GET,
        .handler = dashboard_get_handler,
        .user_ctx = ctx
    };
    httpd_register_uri_handler(server, &uri);
}
