#include "meters_settings_api.h"
#include "meter_manager.h"  // Atualizado para usar o novo manager
#include "esp_log.h"
#include "cJSON.h"

static const char *TAG = "meters_settings_api";

// Função para recuperar as configurações dos contadores
static esp_err_t meters_config_get_handler(httpd_req_t *req) {
    ESP_LOGI(TAG, "Received GET request for /api/v1/config/meters");

    httpd_resp_set_type(req, "application/json");

    cJSON *config = cJSON_CreateObject();

    // Recuperando as configurações dos contadores
    meter_type_t gridmeterType = meter_manager_grid_get_model();
    meter_type_t evsemeterType = meter_manager_evse_get_model();

    ESP_LOGI(TAG, "Grid meter type: %s", meter_type_to_str(gridmeterType));
    ESP_LOGI(TAG, "EVSE meter type: %s", meter_type_to_str(evsemeterType));

    // Adicionando os tipos de contadores ao objeto JSON
    cJSON_AddStringToObject(config, "gridmeter", meter_type_to_str(gridmeterType));
    cJSON_AddStringToObject(config, "evsemeter", meter_type_to_str(evsemeterType));

    // Convertendo o objeto JSON para uma string
    const char *json_str = cJSON_Print(config);
    ESP_LOGI(TAG, "Returning meters config: %s", json_str);

    httpd_resp_sendstr(req, json_str);

    // Liberação da memória
    free((void *)json_str);
    cJSON_Delete(config);

    return ESP_OK;
}

// Função para atualizar as configurações dos contadores
static esp_err_t meters_config_post_handler(httpd_req_t *req) {
    ESP_LOGI(TAG, "Received POST request for /api/v1/config/meters");

    char buf[512];
    int len = httpd_req_recv(req, buf, sizeof(buf) - 1);

    if (len <= 0) {
        ESP_LOGE(TAG, "Received empty body in POST request");
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body");
        return ESP_FAIL;
    }

    buf[len] = '\0';  // Garantir que a string está terminada

    ESP_LOGI(TAG, "Received POST data: %s", buf);

    cJSON *json = cJSON_Parse(buf);
    if (!json) {
        ESP_LOGE(TAG, "Failed to parse JSON data");
        // Resposta detalhada de erro
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON format");
        return ESP_FAIL;
    }

    // Atualizando os contadores
    cJSON *gridmeter = cJSON_GetObjectItem(json, "gridmeter");
    if (gridmeter) {
        meter_type_t gridType = string_to_meter_type(gridmeter->valuestring);  // Usando a função string_to_meter_type
        ESP_LOGI(TAG, "Updating grid meter type to: %s", gridmeter->valuestring);
        meter_manager_grid_set_model(gridType);
    }

    cJSON *evsemeter = cJSON_GetObjectItem(json, "evsemeter");
    if (evsemeter) {
        meter_type_t evseType = string_to_meter_type(evsemeter->valuestring);  // Usando a função string_to_meter_type
        ESP_LOGI(TAG, "Updating EVSE meter type to: %s", evsemeter->valuestring);
        meter_manager_evse_set_model(evseType);
    }

    cJSON_Delete(json);
    httpd_resp_sendstr(req, "Meters updated successfully");

    ESP_LOGI(TAG, "Meters configuration updated successfully");

    return ESP_OK;
}

// Registrando os manipuladores de URI para os contadores
void register_meters_settings_handlers(httpd_handle_t server, void *ctx) {
    ESP_LOGD(TAG, "Registering URI handlers for meters settings");

    // URI para o método GET
    httpd_uri_t meters_get_uri = {
        .uri = "/api/v1/config/meters",
        .method = HTTP_GET,
        .handler = meters_config_get_handler,
        .user_ctx = ctx
    };
    ESP_LOGD(TAG, "Registering GET handler for /api/v1/config/meters");
    httpd_register_uri_handler(server, &meters_get_uri);

    // URI para o método POST
    httpd_uri_t meters_post_uri = {
        .uri = "/api/v1/config/meters",
        .method = HTTP_POST,
        .handler = meters_config_post_handler,
        .user_ctx = ctx
    };
    ESP_LOGD(TAG, "Registering POST handler for /api/v1/config/meters");
    httpd_register_uri_handler(server, &meters_post_uri);
}
