#include <Wire.h>
  #include <Adafruit_GFX.h>
  #include <Adafruit_SSD1306.h>
  #include <WiFi.h>
  #include <HTTPClient.h>
  #include <ArduinoJson.h>
  #include <iostream>
  #include <string>

// Screen setup
  #define SCREEN_WIDTH 128
  #define SCREEN_HEIGHT 64
  #define OLED_RESET    -1
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Rotary Encoder pins
#define ENCODER_CLK 2     // Clock pin
#define ENCODER_DT 3      // Data pin
#define ENCODER_SW 4      // Push-button pin

// Variables for rotary encoder
volatile int encoderDirection = 0; // Tracks direction of rotation (-1 or +1)
bool encoderButtonPressed = false;

// Match JSON data
String data = "";


  const uint8_t ADS[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xf0, 0x00, 0x00, 0x1e, 0x10, 0x00, 0x00, 0x70, 0x10, 0x00, 0x00, 0xc7, 0x30, 0x00, 
    0x01, 0x9d, 0xe0, 0x00, 0x03, 0x30, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 
    0x03, 0x18, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 
    0x00, 0x19, 0xc0, 0x00, 0x00, 0x0c, 0x6f, 0xf8, 0x00, 0x04, 0x38, 0x08, 0x00, 0x06, 0x03, 0xf8, 
    0x00, 0x7c, 0x0e, 0x00, 0x01, 0xc1, 0xc8, 0x00, 0x07, 0x1f, 0x18, 0x00, 0x0c, 0x7e, 0x70, 0x00, 
    0x18, 0xf8, 0xc0, 0x00, 0x33, 0x83, 0x80, 0x00, 0x20, 0x1e, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00
  };

  const uint8_t BRH[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x00, 
    0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x80, 0x40, 0x01, 0x00, 0xc0, 0x20, 
    0x01, 0x80, 0x40, 0x20, 0x00, 0x80, 0xd0, 0x40, 0x00, 0x80, 0xa0, 0x40, 0x00, 0x83, 0x61, 0x80, 
    0x00, 0x82, 0xc0, 0x40, 0x00, 0x82, 0xcc, 0x20, 0x00, 0x97, 0x7e, 0x20, 0x00, 0x97, 0xbb, 0x20, 
    0x01, 0xb7, 0xbb, 0xa0, 0x01, 0x33, 0x3f, 0xa0, 0x01, 0x3f, 0xff, 0xe0, 0x01, 0x3f, 0xff, 0xc0, 
    0x01, 0x3f, 0xff, 0x80, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  const uint8_t HBH[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x3f, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x0f, 0xfc, 0x80, 0x00, 0x3f, 0xe0, 0x80, 
    0x00, 0xff, 0x00, 0x80, 0x01, 0xf8, 0x00, 0x80, 0x03, 0xc0, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 
    0x02, 0x00, 0x00, 0x80, 0x02, 0x07, 0xc1, 0x80, 0x02, 0x0f, 0xf3, 0x80, 0x02, 0x1f, 0xff, 0x00, 
    0x02, 0x3c, 0x3e, 0x00, 0x02, 0x70, 0x1c, 0x00, 0x03, 0xe3, 0x84, 0x00, 0x01, 0xc7, 0xfc, 0x00, 
    0x00, 0x4e, 0x18, 0x00, 0x00, 0x58, 0x70, 0x00, 0x00, 0x73, 0xc0, 0x00, 0x00, 0x19, 0x00, 0x00, 
    0x00, 0x0b, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };



  const uint8_t MLR[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x38, 0x3c, 0x00, 
    0x00, 0x70, 0x0e, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x01, 0xdf, 0xf9, 0x80, 0x01, 0x8f, 0x3d, 0x80, 
    0x01, 0x8f, 0x3c, 0xc0, 0x03, 0x1e, 0x3c, 0xc0, 0x03, 0x1e, 0x3c, 0xc0, 0x03, 0x3e, 0x7c, 0xc0, 
    0x03, 0x3e, 0xf8, 0xc0, 0x03, 0x3f, 0xf8, 0xc0, 0x01, 0xbd, 0xf0, 0xc0, 0x01, 0xbc, 0x70, 0x80, 
    0x01, 0xdc, 0x71, 0x80, 0x00, 0xc8, 0x73, 0x80, 0x00, 0x70, 0x32, 0x00, 0x00, 0x3c, 0x3c, 0x00, 
    0x00, 0x1f, 0xf8, 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0a, 0x00
  };

  const uint8_t MLS[] PROGMEM = {
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 
	  0x00, 0x01, 0xc0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 
	  0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 
	  0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xf0, 
	  0x03, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x3f, 0xfc, 0x00, 
	  0x00, 0x3f, 0xfc, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x7f, 0xfe, 0x00, 
	  0x00, 0xfe, 0x7f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x01, 0xc0, 0x03, 0x80
  };

  const uint8_t PRS[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x1f, 0xfc, 0x00, 0x01, 0xfc, 0x3f, 0x80, 0x03, 0xf0, 0x0f, 0xe0, 0x0f, 0xe0, 0xf7, 0xf0, 
    0x1f, 0xc7, 0xfb, 0xf8, 0x0f, 0xcf, 0x39, 0xf0, 0x07, 0x8f, 0x01, 0xe0, 0x1f, 0x8f, 0xc1, 0xf8, 
    0x07, 0x87, 0xf1, 0xe0, 0x0f, 0x80, 0x71, 0xf0, 0x1f, 0xd8, 0xf1, 0xf8, 0x1f, 0xdf, 0xe3, 0xf8, 
    0x0f, 0xef, 0x87, 0xf0, 0x03, 0xf0, 0x0f, 0xe0, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x1f, 0xfc, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
  };

  const uint8_t SYS[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x01, 0xfc, 0xc0, 
    0x00, 0x07, 0x98, 0x60, 0x00, 0x0e, 0x10, 0x20, 0x00, 0x1c, 0x30, 0x20, 0x00, 0x38, 0x78, 0x60, 
    0x00, 0x70, 0xcc, 0xc0, 0x00, 0xe1, 0x87, 0x80, 0x01, 0xc1, 0x80, 0x00, 0x01, 0x83, 0xf0, 0x00, 
    0x03, 0x83, 0x38, 0x00, 0x03, 0x06, 0x0c, 0x00, 0x07, 0x06, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 
    0x06, 0x0e, 0x06, 0x00, 0x0c, 0x1e, 0x06, 0x00, 0x0c, 0x1e, 0x06, 0x00, 0x0c, 0x1e, 0x06, 0x00, 
    0x0c, 0x1e, 0x06, 0x00, 0x0c, 0x1e, 0x06, 0x00, 0x0c, 0x1c, 0x06, 0x00, 0x0c, 0x00, 0x0c, 0x00, 
    0x06, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x18, 0x00, 0x03, 0x80, 0x38, 0x00, 0x01, 0xc0, 0xf0, 0x00, 
    0x00, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0x00, 0x00
  };

  const uint8_t SYT[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf8, 
    0x00, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0x80, 0x00, 
    0x00, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 
    0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xf8, 0x00, 
    0x03, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x3f, 0x80, 0x00, 
    0x00, 0x7f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 
    0x01, 0xf0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
    0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

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

const char* api_url = "https://cricket-d2fxrbzmh-lukes-projects-4e5a708c.vercel.app/api";

const int statusLedPin = 2; 

// Define game data
String t1 = "";
String t2 = "";
String t1_score_str = "";
String t1_overs = "";
String t2_score_str = "";
String t2_overs = "";

String trails_text_line0 = "";
String trails_text_line1 = "";
String trails_text_line2 = "";

String match_type = "";
int type_offset = 0;

int refresh = 0;

boolean menuScreen = false;

// Menu variables
String dataList[7]; // Holds the menu items
int dataListSize;   // Actual number of items in the array
int currentSelection = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

// Function prototypes
void displayMenu();
void handleEncoder();
void handleButtonPress();
void populateDataList(String json);
void displayMatchDetails(int matchIndex);
void extractMatchData(const String& jsonResponse);
void printScreen();
int leftOffset(String score);
int rightOffset(String score);
int middleOffset(String score);
String swapScore(String score);
String doWifi();
String nullConverter(const String& nullGuyMaybe, boolean runs);

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

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (1);  // Stay in this loop if initialization fails
  }
// Set up the status LED pin
    pinMode(statusLedPin, OUTPUT);
    
    // Connect to WiFi
    WiFi.begin(ssid);
    Serial.println("Connecting to WiFi...");
    while (WiFi.status() != WL_CONNECTED) {
      delay(1000);
      Serial.print(".");
    }
    Serial.println("\nConnected to WiFi!");
    
    // Turn on LED to indicate successful WiFi connection
    digitalWrite(statusLedPin, LOW);

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Loading...");
  display.display();

  // Initialize rotary encoder pins
  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  pinMode(ENCODER_SW, INPUT_PULLUP);

  // Attach interrupt to CLK pin
  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), handleEncoder, FALLING);
  int theTime = millis();
  data = doWifi();
  Serial.println("time taken = ");
  theTime = millis() - theTime;
  Serial.println(theTime);
  populateDataList(data); // Populate the menu with match data from JSON
  displayMenu();      
}

void loop() {
  handleButtonPress();
  if (!menuScreen) {
    // Only update if the encoder direction has changed
    if (encoderDirection != 0) {
      currentSelection += encoderDirection;

      // Loop through the menu
      if (currentSelection >= dataListSize) currentSelection = 0;
      if (currentSelection < 0) currentSelection = dataListSize - 1;

      encoderDirection = 0;  // Reset after processing
      displayMenu();         // Update the menu display
    }
  } else {
    doRefresh();
  }
}

// Parse JSON and populate the data list with matches
void populateDataList(String json) {
  StaticJsonDocument<2048> doc;
  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    Serial.println(F("JSON parsing failed!"));
    dataListSize = 0;
    return;
  }

  JsonArray matches = doc.as<JsonArray>();
  dataListSize = min(7, (int)matches.size()); // Cast size_t to int for compatibility

  for (int i = 0; i < dataListSize; i++) {
    String t1 = matches[i]["t1"].as<String>();
    String t2 = matches[i]["t2"].as<String>();
    String matchType = matches[i]["matchType"].as<String>();
    // Extract 3-letter team codes
    t1 = t1.substring(t1.indexOf('[') + 1, t1.indexOf(']'));
    t2 = t2.substring(t2.indexOf('[') + 1, t2.indexOf(']'));

    dataList[i] = t1 + " vs " + t2 + " (" + matchType + ")";
  }
}


// ISR: Handles rotary encoder changes
void handleEncoder() {
  if (digitalRead(ENCODER_DT) == HIGH) {
    encoderDirection = 1;  // Clockwise
  } else {
    encoderDirection = -1; // Counterclockwise
  }
}

// Check button press and debounce
void handleButtonPress() {
  if (digitalRead(ENCODER_SW) == LOW && (millis() - lastDebounceTime > debounceDelay)) {
    lastDebounceTime = millis();
    encoderButtonPressed = true;
  }

  if (encoderButtonPressed) {
    encoderButtonPressed = false;
    if (!menuScreen) {
      displayMatchDetails(currentSelection);
      menuScreen = true;
    } else {
      displayMenu();
      menuScreen = false;
    }
  }
}

// Display the match details on the next screen
void displayMatchDetails(int matchIndex) {
  StaticJsonDocument<2048> doc;
  DeserializationError error = deserializeJson(doc, data);
  JsonArray matches = doc.as<JsonArray>();

  if (error) {
    Serial.println(F("JSON parsing failed!"));
    dataListSize = 0;
    return;
  }

  String match = matches[matchIndex].as<String>();
  extractMatchData(match);
  printScreen();
}

// Display the menu
void displayMenu() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Select Match:");

  // Display the menu items
  for (int i = 0; i < dataListSize; i++) {
    if (i == currentSelection) {
      display.print("> ");
    } else {
      display.print("  ");
    }
    display.println(dataList[i]);
  }

  display.display();
  delay(100);  // Small delay to ensure the display updates properly
}

void printScreen() {
    display.clearDisplay();
    boolean t1_logo = true;
    boolean t2_logo = true;
    // Display team logos
    if (t1 == "ADS") {
      display.drawBitmap(0, 5, ADS, 32, 32, WHITE);
    } else if (t1 == "BRH") {
      display.drawBitmap(0, 5, BRH, 32, 32, WHITE);
    } else if (t1 == "HBH") {
      display.drawBitmap(0, 5, HBH, 32, 32, WHITE);
    } else if (t1 == "MLR") {
      display.drawBitmap(0, 5, MLR, 32, 32, WHITE);
    } else if (t1 == "MLS") {
      display.drawBitmap(0, 5, MLS, 32, 32, WHITE);
    } else if (t1 == "PRS") {
      display.drawBitmap(0, 5, PRS, 32, 32, WHITE);
    } else if (t1 == "SYS") {
      display.drawBitmap(0, 5, SYS, 32, 32, WHITE);
    } else if (t1 == "SYT") {
      display.drawBitmap(0, 5, SYT, 32, 32, WHITE);
    } else {
      Serial.println("No logo: " + t1);
      t1_logo = false;
    }

    // Display team logos for t2
    if (t2 == "ADS") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, ADS, 32, 32, WHITE);
    } else if (t2 == "BRH") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, BRH, 32, 32, WHITE);
    } else if (t2 == "HBH") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, HBH, 32, 32, WHITE);
    } else if (t2 == "MLR") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, MLR, 32, 32, WHITE);
    } else if (t2 == "MLS") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, MLS, 32, 32, WHITE);
    } else if (t2 == "PRS") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, PRS, 32, 32, WHITE);
    } else if (t2 == "SYS") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, SYS, 32, 32, WHITE);
    } else if (t2 == "SYT") {
      display.drawBitmap(SCREEN_WIDTH - 37, 5, SYT, 32, 32, WHITE);
    } else {
     Serial.println("No logo: " + t2);
     t2_logo = false;
    }

    // Display team names
    if (t1_logo) {
      display.setCursor(leftOffset(t1), 0);
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.print(t1);
    } else {
      display.setCursor(0, 16);
      display.setTextSize(2);
      display.print(t1);
    }

    if (t2_logo) {
      display.setCursor(rightOffset(t1), 0);
      display.setTextSize(1);
      display.print(t2);
    } else {
      display.setCursor(SCREEN_WIDTH - 36, 16);
      display.setTextSize(2);
      display.print(t2);
    }

    // Display status
    display.setCursor(middleOffset(trails_text_line0), 6); // Adjust to center
    display.setTextSize(1);
    
    display.setTextColor(WHITE);
    display.print(trails_text_line0);
    
    display.setCursor(middleOffset(trails_text_line1), 16); // Adjust to center
    display.print(trails_text_line1);

    display.setCursor(middleOffset(trails_text_line2), 26); // Adjust to center
    display.print(trails_text_line2);

    display.setCursor(type_offset, 50); // Adjust to center
    display.print(match_type);

    display.setCursor(leftOffset(t1_score_str), 45);
    display.print(swapScore(t1_score_str));
    display.setCursor(leftOffset(t1_overs), 55);
    display.print(t1_overs);
    
    display.setCursor(rightOffset(t2_score_str), 45);
    display.print(swapScore(t2_score_str));
    display.setCursor(rightOffset(t2_overs), 55);
    display.print(t2_overs);
    
    display.display();
  }

  String doWifi() {
      String response = "";
      if (WiFi.status() == WL_CONNECTED) {
      HTTPClient http;

      // Start the HTTP request
      http.begin(api_url);
      int httpResponseCode = http.GET();

      if (httpResponseCode > 0) {
        Serial.printf("HTTP Response Code: %d\n", httpResponseCode);

        // Get the response payload
        response = http.getString();
      } else {
        Serial.printf("Error in HTTP request: %s\n", http.errorToString(httpResponseCode).c_str());
      }

      // Close connection
      http.end();
    } else {
      Serial.println("WiFi Disconnected. Reconnecting...");
      digitalWrite(statusLedPin, LOW); // Turn off the LED when disconnected
      WiFi.reconnect(); // Attempt to reconnect
    }
    return response;
  }

void extractMatchData(const String& jsonResponse) {
      // Create a DynamicJsonDocument to parse the JSON
      StaticJsonDocument<1024> doc;
      
      // Deserialize the JSON response
      DeserializationError error = deserializeJson(doc, jsonResponse);
      
      if (error) {
          Serial.print("Failed to parse JSON: ");
          Serial.println(error.f_str());
          return;
      }

      // Extract team names and abbreviations
      String t1_full = doc["t1"].as<String>();
      String t2_full = doc["t2"].as<String>();

      String t1_fulls = doc["t1s"].as<String>();
      String t2_fulls = doc["t2s"].as<String>();
      
      t1 = t1_full.substring(t1_full.indexOf("[") + 1, t1_full.indexOf('[') + 4);
      t2 = t2_full.substring(t2_full.indexOf("[") + 1, t2_full.indexOf('[') + 4);
      
    t1_score_str = nullConverter(t1_fulls.substring(0, t1_fulls.indexOf(" ")), true);
    t2_score_str = nullConverter(t2_fulls.substring(0, t2_fulls.indexOf(" ")), true);



      match_type = doc["matchType"].as<String>();
      if (match_type == "test") {
        type_offset = SCREEN_WIDTH / 2 - 12;
      } else {
        type_offset = SCREEN_WIDTH / 2 - 9;
      }

      t1_overs = nullConverter(t1_fulls.substring(t1_fulls.indexOf("("), t1_fulls.indexOf(")") + 1), false);
      t2_overs = nullConverter(t2_fulls.substring(t2_fulls.indexOf("("), t2_fulls.indexOf(")") + 1), false);

      int t1_score = t1_score_str.substring(0, t1_score_str.indexOf("/")).toInt();
      int t2_score = t2_score_str.substring(0, t2_score_str.indexOf("/")).toInt();

      if (t1_score >= t2_score) {
          trails_text_line0 = t2;
          trails_text_line1 = "trail by";
          trails_text_line2 = String(t1_score - t2_score);
      } else {
        trails_text_line0 = t2;
          trails_text_line1 = "lead by";
          trails_text_line2 = String(t2_score - t1_score);
      }
  } 


String nullConverter(const String& nullGuyMaybe, boolean runs) {
  if (nullGuyMaybe == "") {
    if (runs) {
      return "0/0";
    } else {
      return "(0)";
    }
  } else {
    return nullGuyMaybe;
  }
}

int middleOffset(String strings) {
  int length = strings.length();
  int dude = (SCREEN_WIDTH / 2) - 3* (length);
  return dude;
}

int rightOffset(String strings) {
  int length = strings.length();
  int dude = (SCREEN_WIDTH - 18 - 3 * (length));
  return dude;
}

int leftOffset(String strings) {
  int length = strings.length();
  int dude = (18 - 3 * (length));
  return dude;
}

String swapScore(String score) {
  int separatorIndex = score.indexOf('/');
  String firstPart = score.substring(0, separatorIndex);
  String secondPart = score.substring(separatorIndex + 1);
  return secondPart + "/" + firstPart;
}

void doRefresh() {
  if (refresh >= 127) {
    data = doWifi();
    refresh = 0;
    for (int i = 0; i <= 127; i++) {
      display.drawPixel(i, 63, SSD1306_BLACK);
      display.display();
    }
  } else {
    refresh++;
    display.drawPixel(refresh, 63, SSD1306_WHITE);
    display.display();
  }
  delay(1);
}