// =========================
// ocpp_api.c
// =========================
#include "ocpp.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_http_server.h"
#include "cJSON.h"
#include <string.h>

static const char *TAG = "ocpp_api";

static esp_err_t ocpp_get_status_handler(httpd_req_t *req) {
    ESP_LOGD(TAG, "GET /api/v1/ocpp");
    httpd_resp_set_type(req, "application/json");

    char server[64] = {0};
    char charge_id[64] = {0};
    ocpp_get_server(server);
    ocpp_get_charge_id(charge_id);

    cJSON *status = cJSON_CreateObject();
    cJSON_AddBoolToObject(status, "connected", ocpp_is_connected());
    cJSON_AddStringToObject(status, "server", server);
    cJSON_AddStringToObject(status, "charge_id", charge_id);

    char *str = cJSON_PrintUnformatted(status);
    httpd_resp_sendstr(req, str);

    free(str);
    cJSON_Delete(status);
    return ESP_OK;
}

static esp_err_t ocpp_get_config_handler(httpd_req_t *req) {
    ESP_LOGD(TAG, "GET /api/v1/config/ocpp");
    httpd_resp_set_type(req, "application/json");

    char server[64] = {0};
    char charge_id[64] = {0};
    bool enabled = ocpp_get_enabled();
    ocpp_get_server(server);
    ocpp_get_charge_id(charge_id);

    cJSON *json = cJSON_CreateObject();
    cJSON_AddBoolToObject(json, "enabled", enabled);
    cJSON_AddStringToObject(json, "url", server);
    cJSON_AddStringToObject(json, "chargeBoxId", charge_id);

    char *str = cJSON_PrintUnformatted(json);
    httpd_resp_sendstr(req, str);

    free(str);
    cJSON_Delete(json);
    return ESP_OK;
}

static esp_err_t ocpp_post_config_handler(httpd_req_t *req) {
    ESP_LOGD(TAG, "POST /api/v1/config/ocpp");

    char buf[512];
    int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
    if (len <= 0) {
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body");
        return ESP_FAIL;
    }
    buf[len] = '\0';

    cJSON *json = cJSON_Parse(buf);
    if (!json) {
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
        return ESP_FAIL;
    }

    cJSON *enabled = cJSON_GetObjectItem(json, "enabled");
    if (cJSON_IsBool(enabled)) {
        ocpp_set_enabled(cJSON_IsTrue(enabled));
    }

    cJSON *url = cJSON_GetObjectItem(json, "url");
    if (cJSON_IsString(url)) {
        ocpp_set_server(url->valuestring);
    }

    cJSON *id = cJSON_GetObjectItem(json, "chargeBoxId");
    if (cJSON_IsString(id)) {
        ocpp_set_charge_id(id->valuestring);
    }

    cJSON_Delete(json);
    httpd_resp_sendstr(req, "OCPP config atualizada com sucesso");
    return ESP_OK;
}

void register_ocpp_handlers(httpd_handle_t server, void *ctx) {
    httpd_uri_t status_uri = {
        .uri = "/api/v1/ocpp",
        .method = HTTP_GET,
        .handler = ocpp_get_status_handler,
        .user_ctx = ctx
    };
    httpd_register_uri_handler(server, &status_uri);

    httpd_uri_t get_uri = {
        .uri = "/api/v1/config/ocpp",
        .method = HTTP_GET,
        .handler = ocpp_get_config_handler,
        .user_ctx = ctx
    };
    httpd_register_uri_handler(server, &get_uri);

    httpd_uri_t post_uri = {
        .uri = "/api/v1/config/ocpp",
        .method = HTTP_POST,
        .handler = ocpp_post_config_handler,
        .user_ctx = ctx
    };
    httpd_register_uri_handler(server, &post_uri);
}
