#include "WebServer.hpp"
#include "../WidgetManager.hpp"
#include "esp_log.h"
#include <cstring>

static const char* TAG = "WebServer";

esp_err_t WebServer::getConfigHandler(httpd_req_t* req) {
    char* buf = new char[32768];
    if (buf == nullptr) {
        httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Out of memory");
        return ESP_FAIL;
    }

    WidgetManager::instance().getConfigJson(buf, 32768);

    httpd_resp_set_type(req, "application/json");
    httpd_resp_send(req, buf, strlen(buf));

    delete[] buf;
    return ESP_OK;
}

esp_err_t WebServer::postConfigHandler(httpd_req_t* req) {
    int total_len = req->content_len;
    if (total_len > 32768) {
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Content too large");
        return ESP_FAIL;
    }

    char* buf = new char[total_len + 1];
    if (buf == nullptr) {
        httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Out of memory");
        return ESP_FAIL;
    }

    int received = 0;
    while (received < total_len) {
        int ret = httpd_req_recv(req, buf + received, total_len - received);
        if (ret <= 0) {
            delete[] buf;
            httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Receive failed");
            return ESP_FAIL;
        }
        received += ret;
    }
    buf[received] = '\0';

    bool success = WidgetManager::instance().updateConfigFromJson(buf);
    delete[] buf;

    cJSON* json = cJSON_CreateObject();
    if (success) {
        cJSON_AddStringToObject(json, "status", "ok");
    } else {
        cJSON_AddStringToObject(json, "status", "error");
        cJSON_AddStringToObject(json, "message", "Invalid JSON");
    }
    return sendJsonObject(req, json);
}

esp_err_t WebServer::postSaveHandler(httpd_req_t* req) {
    ESP_LOGI(TAG, "Saving and applying configuration");
    WidgetManager::instance().saveAndApply();

    cJSON* json = cJSON_CreateObject();
    cJSON_AddStringToObject(json, "status", "ok");
    return sendJsonObject(req, json);
}

esp_err_t WebServer::postResetHandler(httpd_req_t* req) {
    ESP_LOGI(TAG, "Resetting to defaults");
    WidgetManager::instance().resetToDefaults();

    cJSON* json = cJSON_CreateObject();
    cJSON_AddStringToObject(json, "status", "ok");
    return sendJsonObject(req, json);
}
