#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

#define USE_SERIAL Serial

const char* ssid     = "Wokwi-GUEST"; // Change this to your WiFi SSID
const char* password = ""; // Change this to your WiFi password
int RGB1_r = 19, RGB1_g = 18, RGB1_b = 5,
    RGB2_r = 17, RGB2_g = 16, RGB2_b = 4,
    RGB3_r = 0, RGB3_g = 2, RGB3_b = 15;

void setup() {

  USE_SERIAL.begin(115200);
  USE_SERIAL.println();
  USE_SERIAL.println();
  USE_SERIAL.println();

  pinMode(RGB1_r, OUTPUT);
  pinMode(RGB1_g, OUTPUT);
  pinMode(RGB1_b, OUTPUT);
  pinMode(RGB2_r, OUTPUT);
  pinMode(RGB2_g, OUTPUT);
  pinMode(RGB2_b, OUTPUT);
  pinMode(RGB3_r, OUTPUT);
  pinMode(RGB3_g, OUTPUT);
  pinMode(RGB3_b, OUTPUT);

  for (uint8_t t = 4; t > 0; t--) {
    USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
    USE_SERIAL.flush();
    delay(1000);
  }
  WiFi.mode(WIFI_STA);

  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    while (WiFi.status() != WL_CONNECTED) {
      WiFi.begin(ssid, password);  // Connect to WPA/WPA2 network. Change this line if using open or WEP network
      Serial.print(".");
      delay(5000);
    }
    Serial.println("\nConnected.");
  }
}

void loop() {
  // wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {

    HTTPClient http;

    USE_SERIAL.print("[HTTP] begin...\n");
    // configure traged server and url
    //http.begin("https://www.howsmyssl.com/a/check", ca); //HTTPS
    http.begin("https://data.moenv.gov.tw/api/v2/aqx_p_02?api_key=e8dd42e6-9b8b-43f8-991e-b3dee723a52d&limit=1000&sort=datacreationdate%20desc&format=JSON"); //HTTP

    USE_SERIAL.print("[HTTP] GET...\n");
    // start connection and send HTTP header
    int httpCode = http.GET();

    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        // String input;

        DynamicJsonDocument doc(16384);
        DeserializationError error = deserializeJson(doc, payload);

        if (error) {
          Serial.print("deserializeJson() failed: ");
          Serial.println(error.c_str());
          return;
        }

        for (JsonObject field : doc["fields"].as<JsonArray>()) {
          const char* field_id = field["id"]; // "site", "county", "pm25", "datacreationdate", "itemunit"
          const char* field_type = field["type"]; // "text", "text", "text", "text", "text"
          const char* field_info_label = field["info"]["label"]; // "測站名稱", "縣市名稱", "細懸浮微粒濃度", "資料建置日期", "測項單位"
        }

        const char* resource_id = doc["resource_id"]; // "c1f31192-babd-4105-b880-a4c2e23a3276"

        const char* extras_api_key = doc["__extras"]["api_key"]; // "e8dd42e6-9b8b-43f8-991e-b3dee723a52d"

        bool include_total = doc["include_total"]; // true
        const char* total = doc["total"]; // "78"
        const char* resource_format = doc["resource_format"]; // "object"
        const char* limit = doc["limit"]; // "1000"
        const char* offset = doc["offset"]; // "0"

        const char* links_start = doc["_links"]["start"];
        const char* links_next = doc["_links"]["next"];

        for (JsonObject record : doc["records"].as<JsonArray>()) {

          const char* record_site = record["site"]; // "大城", "富貴角", "麥寮", "關山", "馬公", "金門", "馬祖", "埔里", "復興", ...
          const char* record_county = record["county"]; // "彰化縣", "新北市", "雲林縣", "臺東縣", "澎湖縣", "金門縣", "連江縣", "南投縣", ...
          const char* record_pm25 = record["pm25"]; // "28", "24", "27", "6", "22", "38", "20", "2", "36", "21", ...
          const char* record_datacreationdate = record["datacreationdate"]; // "2023-11-30 15:00", "2023-11-30 ...
          const char* record_itemunit = record["itemunit"]; // "μg/m3", "μg/m3", "μg/m3", "μg/m3", "μg/m3", ...

          if (record["site"] == "金門" || record["site"] == "馬祖" || record["site"] == "臺南") {
            String site = record["site"];
            String county = record["county"];
            String pm25 = record["pm25"];
            String datacreationdate =  record["datacreationdate"];
            String itemunit =  record["itemunit"];
            Serial.println(datacreationdate + site + "PM2.5=" + pm25 + itemunit);
          }

          if (record["site"] == "金門") {
            int PM25 = record["pm25"];
            if (PM25 <= 50) {
              analogWrite(RGB1_r, 0);
              analogWrite(RGB1_g, 255);
              analogWrite(RGB1_b, 0);
            } else if (PM25 >= 51 && PM25 <= 100) {
              analogWrite(RGB1_r, 255);
              analogWrite(RGB1_g, 255);
              analogWrite(RGB1_b, 0);
            } else if (PM25 >= 101 && PM25 <= 150) {
              analogWrite(RGB1_r, 255);
              analogWrite(RGB1_g, 128);
              analogWrite(RGB1_b, 0);
            } else if (PM25 >= 151 && PM25 <= 200) {
              analogWrite(RGB1_r, 255);
              analogWrite(RGB1_g, 0);
              analogWrite(RGB1_b, 0);
            } else if (PM25 >= 201 && PM25 <= 300) {
              analogWrite(RGB1_r, 128);
              analogWrite(RGB1_g, 0);
              analogWrite(RGB1_b, 255);
            } else if (PM25 >= 301 && PM25 <= 500) {
              analogWrite(RGB1_r, 128);
              analogWrite(RGB1_g, 0);
              analogWrite(RGB1_b, 0);
            } else {
              Serial.println("失敗");
            }
          }
          if (record["site"] == "馬祖") {
            int PM25 = record["pm25"];
            if (PM25 <= 50) {
              analogWrite(RGB2_r, 0);
              analogWrite(RGB2_g, 255);
              analogWrite(RGB1_b, 0);
            } else if (PM25 >= 51 && PM25 <= 100) {
              analogWrite(RGB2_r, 255);
              analogWrite(RGB2_g, 255);
              analogWrite(RGB2_b, 0);
            } else if (PM25 >= 101 && PM25 <= 150) {
              analogWrite(RGB2_r, 255);
              analogWrite(RGB2_g, 128);
              analogWrite(RGB2_b, 0);
            } else if (PM25 >= 151 && PM25 <= 200) {
              analogWrite(RGB2_r, 255);
              analogWrite(RGB2_g, 0);
              analogWrite(RGB2_b, 0);
            } else if (PM25 >= 201 && PM25 <= 300) {
              analogWrite(RGB2_r, 128);
              analogWrite(RGB2_g, 0);
              analogWrite(RGB2_b, 255);
            } else if (PM25 >= 301 && PM25 <= 500) {
              analogWrite(RGB2_r, 128);
              analogWrite(RGB2_g, 0);
              analogWrite(RGB2_b, 0);
            } else {
              Serial.println("失敗");
            }
          }
          if (record["site"] == "臺南") {
            int PM25 = record["pm25"];
            if (PM25 <= 50) {
              analogWrite(RGB3_r, 0);
              analogWrite(RGB3_g, 255);
              analogWrite(RGB3_b, 0);
            } else if (PM25 >= 51 && PM25 <= 100) {
              analogWrite(RGB3_r, 255);
              analogWrite(RGB3_g, 255);
              analogWrite(RGB3_b, 0);
            } else if (PM25 >= 101 && PM25 <= 150) {
              analogWrite(RGB3_r, 255);
              analogWrite(RGB3_g, 128);
              analogWrite(RGB3_b, 0);
            } else if (PM25 >= 151 && PM25 <= 200) {
              analogWrite(RGB3_r, 255);
              analogWrite(RGB3_g, 0);
              analogWrite(RGB3_b, 0);
            } else if (PM25 >= 201 && PM25 <= 300) {
              analogWrite(RGB3_r, 128);
              analogWrite(RGB3_g, 0);
              analogWrite(RGB3_b, 255);
            } else if (PM25 >= 301 && PM25 <= 500) {
              analogWrite(RGB3_r, 128);
              analogWrite(RGB3_g, 0);
              analogWrite(RGB3_b, 0);
            } else {
              Serial.println("失敗");
            }
          }
        }
        //USE_SERIAL.println(payload);
      }
    } else {
      USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  }

  delay(5000);
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
rgb1:R
rgb1:COM
rgb1:G
rgb1:B
rgb2:R
rgb2:COM
rgb2:G
rgb2:B
rgb3:R
rgb3:COM
rgb3:G
rgb3:B