// #include <FastLED.h>
// #include <WiFi.h>
// #include <HTTPClient.h>
// #include <ArduinoJson.h>


// // How many leds in your strip?
// #define NUM_LEDS 8

// // For led chips like Neopixels, which have a data line, ground, and power, you just
// // need to define DATA_PIN.
// #define DATA_PIN 2

// // Define the array of leds
// CRGB leds[NUM_LEDS];
// // Airport list
// String icao[] = {"KRPH", "KBKD", "K6P9", "KETN", "KGZN", "KABI", "KDYS", "KSWW"};

// void setup() { 
// 	Serial.begin(115200);
// 	Serial.println("resetting");
// 	FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
// 	FastLED.setBrightness(100);

//   fetchMetars(DATA_PIN, icao, NUM_LEDS);
// }

// void fetchMetars(int pin, String icao[], int numIcao) {
//   WiFiClientSecure client;
//   client.setInsecure();

//   HTTPClient http;
//   http.useHTTP10(true);
  
//   // String url = "https://aviationweather.gov/api/data/metar?ids=" + icao[0] + delim + icao[1] + delim + icao[2] + "&format=json";
//   String url = "https://aviationweather.gov/api/data/metar?ids=";
//   for (int i = 0; i < numIcao; i++) {
//     if (i < numIcao - 1) {
//       url += icao[i] + "%2C";
//     } else {
//       url += icao[i];
//     }
//   }
//   url += "&format=json";
//   Serial.println("Pulling METARs from: " + url);

//   http.begin(client, url);
//   // http.begin(url);
//   int responseCode = http.GET();
//   String result = http.getString();
//   Serial.println("JSON Recieved: " + result);

//   DynamicJsonDocument doc(16384);
//   DeserializationError error = deserializeJson(doc, result);

//   // Serial.println("METAR: " + doc[0]["rawOb"]);

//   // Test if parsing succeeds.
//   if (error) {
//     Serial.print(F("deserializeJson() failed: "));
//     Serial.println(error.f_str());
//     return;
//   }

//   // Note this implementation only chceks the lowest reported clouds
//   for (int i = 0; i < numIcao; i++) {
//     JsonObject root = doc[i];
//     String metarRaw = root["rawOb"];
//     // Serial.println(metarRaw);

//     String lowest_cover = root["clouds"][0]["cover"];
//     String lowest_base = root["clouds"][0]["base"];
//     String visib = root["visib"];
//     Serial.println(icao[i] + " ceiling: " + lowest_cover + " @ " + lowest_base + " ft\tVisibility: " + visib + " mi");
    
//     bool ceiling = false;
//     int ceiling_num = -1;

//       // if clouds > 0:
//           // for x in range(len(clouds)):
//               // cloud = clouds[x]
//     if (isDigit(lowest_base[0])) {
//       if (lowest_cover == "BKN" || lowest_cover == "OVC") {
//         // lowest_cover = cloud['cover']
//         // lowest_base = cloud['base']
//         ceiling = true;
//         // ceiling_num = x;
//         // break
//       }
//     } else {
//       Serial.println("No clouds!");
//     }
  

//     float vis = 0;
//     if (visib == "10+") {
//       vis = 10;
//     } else {
//       vis = visib.toInt();
//     }

//     int base = lowest_base.toInt();

//     if (lowest_cover == "CLR") {
//       Serial.println("CLR WX!");
//       leds[i] = CRGB(0, 255, 0);
//       Serial.println(icao[i] + " is VFR");
//     } else {
//       // Serial.println("CEILING!");
//       if (base < 500 || vis < 1) {
//         leds[i] = CRGB(255, 0, 255);
//         Serial.println(icao[i] + " is LIFR");
//       } else if (base < 1000 || vis < 3) {
//         leds[i] = CRGB(255, 0, 0);
//         Serial.println(icao[i] + " is IFR");
//       } else if (base < 3000 || vis < 5) {
//         leds[i] = CRGB(0, 0, 255);
//         Serial.println(icao[i] + " is MVFR");
//       // }
//       } else {
//         Serial.println("NO CEILING!");
//         leds[i] = CRGB(0, 255, 0);
//         Serial.println(icao[i] + " is VFR");
//       }
//     }
//     Serial.println("\n");
//     FastLED.show();
//   }
// }

// void loop() {
//   // Loop through each LED and set it to blue
//   // for (int dot = 0; dot < NUM_LEDS; dot++) {
//   //   leds[dot] = CRGB::Blue;   // Set the current LED to blue
//   //   FastLED.show();           // Update LEDs
//   //   leds[dot] = CRGB::Black;  // Clear the current LED
//   //   delay(100);                // Wait for a short period before moving to the next LED
//   // }
// }


#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <FastLED.h>  // Include FastLED library

const char* ssid = "Wokwi-GUEST";
const char* password = "";


#define DATA_PIN_1 2
#define NUM_ICAO 8
#define NUM_LEDS 8    // Number of LEDs in the chain
#define BRIGHTNESS 8
#define UPDATE_IN_SEC 300 // Update interval in seconds (Default is 5 min)

unsigned long lastMillis;
CRGB leds[NUM_LEDS];  // Array to hold LED color data
String ICAOS[NUM_ICAO] = {"KBVY", "KLWM", "KASH", "KFIT", "KBED", "KBOS", "KGHG", "KPYM"}; 

void setup() { 
  Serial.begin(115200); 

  FastLED.addLeds<NEOPIXEL, DATA_PIN_1>(leds, NUM_LEDS);  // Initialize LEDs
  FastLED.setBrightness(BRIGHTNESS); // Set LED brightness
  for (int n = 0; n < NUM_ICAO; n++) {
    leds[n] = CRGB::White;
  }
  FastLED.show();

  WiFi.begin(ssid, password);

  Serial.println("");
  Serial.print("Connecting to WiFi");

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  Serial.print("\nOK! IP=");
  Serial.println(WiFi.localIP());

  fetchMetars(ICAOS, NUM_ICAO);
  lastMillis = millis();
}

void fetchMetars(String icao[], int n) {
  // Set up WiFi and HTTP clients
  // WiFiClientSecure client;
  // client.setInsecure(); // Yeah this is not ideal but this shouldn't be a securty issue for this project...
  WiFiClient client;
  HTTPClient http;
  http.useHTTP10(true);

  // Construct URL based off ICAOs supplied above
  String delim = "%2C";
  String url = "https://aviationweather.gov/api/data/metar?ids="; 
  for (int k = 0; k < NUM_ICAO; k++) {
    url += icao[k] + delim;
  }
  url += "&format=json";
  Serial.println("Pulling METARs from: " + url);

  // Fetch JSON based off url
  http.begin(client, url);
  int responseCode = http.GET();
  String result = http.getString();
  Serial.println(result);

  // Setup JSON doc for storage and parsing
  JsonDocument doc;
  DeserializationError error = deserializeJson(doc, result);

  // Test if JSON parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  // Note this implementation only chceks the lowest reported clouds
  for (int i = 0; i < n; i++) {
    JsonObject root = doc[i];
    String metarRaw = root["rawOb"];
    // Serial.println(metarRaw);

    String lowest_cover = root["clouds"][0]["cover"];
    String lowest_base = root["clouds"][0]["base"];
    String visib = root["visib"];
    Serial.println(icao[i] + " ceiling: " + lowest_cover + " @ " + lowest_base + " ft\tVisibility: " + visib + " mi");
    
    bool ceiling = false;
    int ceiling_num = -1;

      // if clouds > 0:
          // for x in range(len(clouds)):
              // cloud = clouds[x]
    if (isDigit(lowest_base[0])) {
      if (lowest_cover == "BKN" || lowest_cover == "OVC") {
        // lowest_cover = cloud['cover']
        // lowest_base = cloud['base']
        ceiling = true;
        // ceiling_num = x;
        // break
      }
    } else {
      Serial.println("No clouds!");
    }
  

    float vis = 0;
    if (visib == "10+") {
      vis = 10;
    } else {
      vis = visib.toInt();
    }

    int base = lowest_base.toInt();

    if (lowest_cover == "CLR") {

      Serial.println("NO CEILING!");
      leds[i] = CRGB::Green;
      Serial.println(icao[i] + " is VFR");
    } else {
      // Serial.println("CEILING!");
      if (base < 500 || vis < 1) {
      leds[i] = CRGB::Purple;
        Serial.println(icao[i] + " is LIFR");
      } else if (base < 1000 || vis < 3) {
      leds[i] = CRGB::Red;
        Serial.println(icao[i] + " is IFR");
      } else if (base < 3000 || vis < 5) {
      leds[i] = CRGB::Blue;
        Serial.println(icao[i] + " is MVFR");
      // }
      } else {
        Serial.println("NO CEILING!");
      leds[i] = CRGB::Green;
        Serial.println(icao[i] + " is VFR");
      }
      FastLED.show();
    }
    
    // Add a delay for a fun effect???
    delay(100);
  }
}

void loop() {
  // Update METARs according to the time set in UPDATE_IN_SEC
  if (millis() - lastMillis >= UPDATE_IN_SEC * 1000UL) {   
    lastMillis = millis();  //get ready for the next iteration
    Serial.println("UPDATING METARS!!!");

    // Dim and set LEDs to white
    FastLED.setBrightness(1);
    for (int n = 0; n < NUM_ICAO; n++) {
      leds[n] = CRGB::White;
    }
    FastLED.show();

    // Refresh METARS
    fetchMetars(ICAOS, NUM_ICAO); 
    // Return LEDS to normal brightness 
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.show();
    Serial.println("UPDATED!!!");
  }
}