#include "networking.h"

#include <string.h>
#include "cJSON.h"
#include "esp_err.h"
#include "esp_http_client.h"
#include "esp_log.h"

static const char* TAG = "JSON";

esp_err_t download_and_parse_json(const char* url) {
  // 1. Create HTTP Client
  esp_http_client_config_t config = {
      .url = url,
      .event_handler = NULL,  // You can add an event handler for more control
  };
  esp_http_client_handle_t client = esp_http_client_init(&config);
  if (client == NULL) {
    ESP_LOGE(TAG, "Failed to create HTTP client");
    return ESP_FAIL;
  }

  // 2. Perform GET request
  esp_err_t err = esp_http_client_perform(client);
  if (err != ESP_OK) {
    ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
    esp_http_client_cleanup(client);
    return err;
  }

  // 3. Check response status code
  int status_code = esp_http_client_get_status_code(client);
  if (status_code != 200) {
    ESP_LOGE(TAG, "HTTP GET request failed with status code: %d", status_code);
    esp_http_client_cleanup(client);
    return ESP_FAIL;
  }

  // 4. Read response content
  int content_length = esp_http_client_get_content_length(client);
  char* response_buffer = malloc(content_length + 1);
  if (response_buffer == NULL) {
    ESP_LOGE(TAG, "Failed to allocate memory for response buffer");
    esp_http_client_cleanup(client);
    return ESP_FAIL;
  }
  int data_read = esp_http_client_read_response(client, response_buffer, content_length);
  if (data_read != content_length) {
    ESP_LOGE(TAG, "Failed to read complete response");
    free(response_buffer);
    esp_http_client_cleanup(client);
    return ESP_FAIL;
  }
  response_buffer[data_read] = '\0';  // Null-terminate the string

  // 5. Parse JSON
  cJSON* root = cJSON_Parse(response_buffer);
  if (root == NULL) {
    const char* error_ptr = cJSON_GetErrorPtr();
    if (error_ptr != NULL) {
      ESP_LOGE(TAG, "Error before: %s", error_ptr);
    }
    free(response_buffer);
    esp_http_client_cleanup(client);
    return ESP_FAIL;
  }

  // 6. Access JSON data
  // Example: Print the value of a key called "message"
  cJSON* message_item = cJSON_GetObjectItem(root, "message");
  if (cJSON_IsString(message_item) && (message_item->valuestring != NULL)) {
    ESP_LOGI(TAG, "Message: %s", message_item->valuestring);
  }

  // 7. Clean up
  cJSON_Delete(root);
  free(response_buffer);
  esp_http_client_cleanup(client);

  return ESP_OK;
}
