#include "wifi.h"
#include "http.h"
#include <cJSON.h>
#include "liquid_crystal.h"

static char http_buffer [512];
const char* title_1 = "ESP-IDF WiFi";
const char* title_2 = "Weather  API";
const uint8_t rs = 5, en = 18, d4 = 19, d5 = 21, d6 = 22, d7 = 23;

static void http_error()
{
  lcd_clear();
  lcd_set_cursor(0, 0);
  const char* error = "  HTTP   ERROR";
  for (int i = 0; i < 14; ++i)
  {
    lcd_write(error[i]);
  }
}

static int get_temp(char* weather)
{
	int tempC = 999;
  const cJSON *temperature = NULL;
  const cJSON *current_weather = NULL;
  cJSON *weather_json = cJSON_Parse(weather);

  if (weather_json == NULL)
  {
    const char *error_ptr = cJSON_GetErrorPtr();
    if (error_ptr != NULL)
    {
      ESP_LOGE("main", "Error before: %s\n", error_ptr);
      cJSON_Delete(weather_json);
      http_error();
      return 0;
    }
  }

  current_weather = cJSON_GetObjectItemCaseSensitive(weather_json, "current_weather");
	temperature = cJSON_GetObjectItemCaseSensitive(current_weather, "temperature");

	if (!cJSON_IsNumber(temperature))
	{
    ESP_LOGE("main", "Temperature NaN");
		cJSON_Delete(weather_json);
		http_error();
    return 0;
	}
	else
	{
    ESP_LOGI("main", "Successfully parsed JSON response.");
		tempC = temperature->valuedouble;
	}

  cJSON_Delete(weather_json);
  return tempC;
}

static void main_loop(void *pvParameters)
{
  while(1)
  {
    http_params params = {
      METEO_SERVER,
      METEO_PORT,
      METEO_REQUEST,
      http_buffer,
      512
    };

    if (http_request(params) == 0)
    {
      http_error();
    }
    else
    {
      int outdoorTempC = get_temp(http_buffer);
      int outdoorTempF = (outdoorTempC * 1.8) + 32.0;
      ESP_LOGI("main", "outdoor temp celsius: %i", outdoorTempC);
      ESP_LOGI("main", "outdoor temp fahrenheit: %i", outdoorTempF);

      char tempbuf [16]; 
      snprintf (tempbuf, 16, "Temp: %i F", outdoorTempF);

      lcd_clear();
      lcd_set_cursor(0, 0);

      for (int i = 0; i < 16; ++i)
      {
        lcd_write(tempbuf[i]);
      }

      char locbuf [16]; 
      snprintf (locbuf, 16, "Berlin, Germany");

      lcd_set_cursor(0, 1);

      for (int i = 0; i < 16; ++i)
      {
        lcd_write(locbuf[i]);
      }
    }

    for(int countdown = 300; countdown >= 0; countdown--)
    {
      ESP_LOGI("main", "%d... ", countdown);
      vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
  }
}

void app_main()
{
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }
  ESP_ERROR_CHECK(ret);
  wifi_init_sta();

  liquid_crystal(rs, en, d4, d5, d6, d7);
  lcd_begin(16, 2);

  lcd_set_cursor(2, 0);
  for (int i = 0; i < 12; i++)
  {
    lcd_write(title_1[i]);
  }

  lcd_set_cursor(2, 1);
  for (int i = 0; i < 12; i++)
  {
    lcd_write(title_2[i]);
  }

  vTaskDelay(2000 / portTICK_PERIOD_MS);
  xTaskCreate(&main_loop, "main_loop", 4096, NULL, 5, NULL);
}