#include <WiFi.h>
#include <HTTPClient.h>
#include "ArduinoJson.h"
#include "SD.h"
#include "SPI.h"

// Pin configuration
#define SD_CS_PIN 5
#define SPEAKER_PIN 25

// SD card file
File audioFile;

bool azan = false;

// User WiFi details
const char* WIFI_SSID = "ooredooBA902F";         // Replace with your Wi-Fi network name (SSID)
const char* WIFI_PASSWORD = "P@SWRD4WIFIEZ123";  // Replace with your Wi-Fi network password

const char* dataTimingsFajr;
const char* dataTimingsSunrise;
const char* dataTimingsDhuhr;
const char* dataTimingsAsr;
const char* dataTimingsMaghrib;
const char* dataTimingsIsha;

// User defined location details
String USER_LATITUDE = "33.88";
String USER_LONGITUDE = "10.08";

// Will be updated with JSON
String CURRENT_TIMEZONE = "Africa/Tunis";
String CURRENT_DATE = "01-01-2000";
String CURRENT_TIME = "00:00:00";
unsigned int CURRENT_MINUTE;
unsigned int CURRENT_HOUR;

// Function prototypes
void initializeSDCard();
void openAudioFile();
void playAudioFile();
void connectToWiFi();
void getTimezone();
void getPrayerTimes();
void checkAzan();

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);  // Start serial communication at 115200 baud
  while (!Serial) {
    // wait for serial port to connect.
  }

  // Initialize SD card
  initializeSDCard();

  // Open audio file
  openAudioFile();

  // Set speaker pin as output
  pinMode(SPEAKER_PIN, OUTPUT);
  digitalWrite(SPEAKER_PIN, LOW);

  Serial.println(" * Prayer Time * ");  // Print once

  connectToWiFi();
}

void loop() {
  if (azan == false) {
    if (WiFi.status() == WL_CONNECTED) {
      getTimezone();
      getPrayerTimes();
      checkTime();
      checkAzan();

      delay(10000);  // Wait for 10 seconds before sending the next request
    } else {
      Serial.println("Lost connection!");
      delay(300);
    }
  } else {
    playAudioFile();
    // When End of audio file reached
    // azan = false
    // Re-connect to wifi
    // Take a look at playAudioFile()
  }
}

void connectToWiFi() {
  // Connect to Wi-Fi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WIFI_SSID);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

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

  Serial.println("");
  Serial.println("Wi-Fi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void getTimezone() {
  WiFiClient client;
  HTTPClient http;

  // Make request to the URL
  String url = "http://worldtimeapi.org/api/timezone/" + CURRENT_TIMEZONE;
  http.begin(client, url);

  // Send the GET request
  int httpResponseCode = http.GET();

  if (httpResponseCode > 0) {
    String response = http.getString();

    StaticJsonDocument<768> doc;
    DeserializationError error = deserializeJson(doc, response);

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

    const char* datetime = doc["datetime"];  // "2023-06-22T12:22:35.847564+01:00"

    // Extract date
    char dateBuffer[11];
    strncpy(dateBuffer, datetime, 10);
    dateBuffer[10] = '\0';

    CURRENT_DATE = dateBuffer;

    // Extract time
    char timeBuffer[6];  // Buffer to hold time component (HH:MM + null terminator)
    strncpy(timeBuffer, datetime + 11, 5);
    timeBuffer[5] = '\0';  // Add null terminator

    CURRENT_TIME = timeBuffer;

    // Extract hour
    char hourBuffer[3];  // Buffer to hold hour component (HH + null terminator)
    strncpy(hourBuffer, datetime + 11, 2);
    hourBuffer[2] = '\0';  // Add null terminator

    CURRENT_HOUR = (int)hourBuffer;

    // Extract minute
    char minuteBuffer[3];  // Buffer to hold minute component (MM + null terminator)
    strncpy(minuteBuffer, datetime + 14, 2);
    minuteBuffer[2] = '\0';  // Add null terminator

    CURRENT_MINUTE = (int)minuteBuffer;

    JsonObject dataMeta = doc["meta"];
    const char* dataMetaTimezone = dataMeta["timezone"];

    CURRENT_TIMEZONE = dataMetaTimezone;

    Serial.println();
    Serial.println(CURRENT_DATE);
    Serial.println(CURRENT_TIME);

    // Close HTTP connection
    http.end();
  } else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
}

void getPrayerTimes() {
  WiFiClient client;
  HTTPClient http;

  // Make request to the URL
  String url = "http://api.aladhan.com/v1/timings/" + CURRENT_DATE + "?latitude=" + USER_LATITUDE + "&longitude=" + USER_LONGITUDE + "&method=1";
  http.begin(client, url);

  // Send the GET request
  int httpResponseCode = http.GET();

  if (httpResponseCode > 0) {
    String response = http.getString();

    DynamicJsonDocument doc(3072);
    DeserializationError error = deserializeJson(doc, response);

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

    int code = doc["code"];
    const char* status = doc["status"];

    JsonObject data = doc["data"];

    JsonObject dataTimings = data["timings"];
    //dataTimingsFajr = dataTimings["Fajr"];
    dataTimingsSunrise = dataTimings["Sunrise"];
    dataTimingsDhuhr = dataTimings["Dhuhr"];
    dataTimingsAsr = dataTimings["Asr"];
    dataTimingsMaghrib = dataTimings["Maghrib"];
    dataTimingsIsha = dataTimings["Isha"];

    dataTimingsFajr = "07:49";

    JsonObject dataMeta = data["meta"];
    const char* dataMetaTimezone = dataMeta["timezone"];

    CURRENT_TIMEZONE = dataMetaTimezone;

    // Print prayer times for the current date and location (RAW data)
    Serial.println();
    Serial.print("Prayer     ");
    Serial.print("Time   ");
    Serial.println();
    Serial.println("----------------");
    Serial.print("Fajr       ");
    Serial.print(dataTimingsFajr);
    Serial.println();
    Serial.print("Sunrise    ");
    Serial.print(dataTimingsSunrise);
    Serial.println();
    Serial.print("Dhuhr      ");
    Serial.print(dataTimingsDhuhr);
    Serial.println();
    Serial.print("Asr        ");
    Serial.print(dataTimingsAsr);
    Serial.println();
    Serial.print("Maghrib    ");
    Serial.print(dataTimingsMaghrib);
    Serial.println();
    Serial.print("Isha       ");
    Serial.print(dataTimingsIsha);
    Serial.println();

    // Close HTTP connection
    http.end();
  } else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
}

// Initialize the SD card
void initializeSDCard() {
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("SD card initialization failed!");
    while (1)
      ;
  }
}

// Open the audio file
void openAudioFile() {
  audioFile = SD.open("/path/to/audio_8.wav");
  if (!audioFile) {
    Serial.println("Error opening audio file!");
    while (1)
      ;
  }
}

// Play audio data from the file
void playAudioFile() {
  int audioSample = audioFile.read();

  if (audioSample == -1) {
    // End of audio file reached
    Serial.println("End of audio file reached!");
    audioFile.close();
    // get back to normal mode
    azan = false;
    connectToWiFi();
  }

  // Repeat outputing sound for better quality
  for (int i = 0; i < 10; i++) {
    // Write audio sample to speaker pin
    dacWrite(SPEAKER_PIN, audioSample);
  }
}

void checkAzan() {
  if (CURRENT_TIME == dataTimingsFajr || CURRENT_TIME == dataTimingsDhuhr || CURRENT_TIME == dataTimingsAsr || CURRENT_TIME == dataTimingsMaghrib || CURRENT_TIME == dataTimingsIsha) {
    // Play audio data from SD card file
    azan = true;
    Serial.println("Azan is playing");
  } else {
    digitalWrite(SPEAKER_PIN, LOW);
  }
}

void extractHourMinute(const char* prayerTime, char* hourBuffer, char* minuteBuffer) {
  strncpy(minuteBuffer, prayerTime + 3, 2);
  minuteBuffer[2] = '\0';
  strncpy(hourBuffer, prayerTime + 0, 2);
  hourBuffer[2] = '\0';
}

void checkTime() {
  char fajrHourBuffer[3];
  char fajrMinuteBuffer[3];
  extractHourMinute(dataTimingsFajr, fajrHourBuffer, fajrMinuteBuffer);
  int fajrHour = atoi(fajrHourBuffer);
  int fajrMinute = atoi(fajrMinuteBuffer);

  Serial.println();
  Serial.print("Fajr hour: ");
  Serial.print(fajrHour);
  Serial.print(" minute: ");
  Serial.println(fajrMinute);


  char dhuhrHourBuffer[3];
  char dhuhrMinuteBuffer[3];
  extractHourMinute(dataTimingsDhuhr, dhuhrHourBuffer, dhuhrMinuteBuffer);
  int dhuhrHour = atoi(dhuhrHourBuffer);
  int dhuhrMinute = atoi(dhuhrMinuteBuffer);

  Serial.print("Dhuhr hour: ");
  Serial.print(dhuhrHour);
  Serial.print(" minute: ");
  Serial.println(dhuhrMinute);

  char asrHourBuffer[3];
  char asrMinuteBuffer[3];
  extractHourMinute(dataTimingsAsr, asrHourBuffer, asrMinuteBuffer);
  int asrHour = atoi(asrHourBuffer);
  int asrMinute = atoi(asrMinuteBuffer);

  Serial.print("Asr hour: ");
  Serial.print(asrHour);
  Serial.print(" minute: ");
  Serial.println(asrMinute);

  char maghribHourBuffer[3];
  char maghribMinuteBuffer[3];
  extractHourMinute(dataTimingsMaghrib, maghribHourBuffer, maghribMinuteBuffer);
  int maghribHour = atoi(maghribHourBuffer);
  int maghribMinute = atoi(maghribMinuteBuffer);

  Serial.print("Maghrib hour: ");
  Serial.print(maghribHour);
  Serial.print(" minute: ");
  Serial.println(maghribMinute);

  char ishaHourBuffer[3];
  char ishaMinuteBuffer[3];
  extractHourMinute(dataTimingsIsha, ishaHourBuffer, ishaMinuteBuffer);
  int ishaHour = atoi(ishaHourBuffer);
  int ishaMinute = atoi(ishaMinuteBuffer);

  Serial.print("Isha hour: ");
  Serial.print(ishaHour);
  Serial.print(" minute: ");
  Serial.println(ishaMinute);
}

Serial print a 30-minute count-down before prayer times and a 30-minute count-up after prayer times. don't use delay() you can use mills() or you can check time from the code.
display a -00:30 to -00:00 and +00:00 to +00:30
You need to know the closet prayer time (next prayer time (count up) and then (current time = prayer time) display (count up)).