#ifndef GUI_TEMPLATE_H
#define GUI_TEMPLATE_H
#include <TFT_eSPI.h>
#include <HTTPClient.h>      // Tego brakowało dla błędu 'HTTPClient'
#include <TJpg_Decoder.h>    // Tego brakowało dla błędu 'TJpgDec'
#include <WiFiClientSecure.h> // DODAJ TO, jeśli nie ma


#define COL_BG      0x0000 // Czarny
#define COL_PANEL   0x10A2
#define COL_GOLD    0xDEAB
#define COL_TEXT    0xFFFF
#define COL_CYAN    0x07FF
#define COL_SILVER  0xC618

// Dodaj na górze pliku, jeśli nie masz
#define COL_LED_GN  0x07E0 // Zielony
#define COL_LED_YL  0xDFE0 // Żółty
#define COL_LED_RD  0xF800 // Czerwony
#define COL_LED_OFF 0x4208 // Ciemny szary (zgaszona dioda)

#define COL_WH       0xFFFF  // Biały
#define COL_LGRAY       0xD69A  // Jasnoszary
#define COL_GRAY        0x8410  // Średni szary (standardowy)
#define COL_DGRAY       0x4208  // Ciemnoszary
#define COL_V_DGRAY     0x2104  // Bardzo ciemny (prawie czarny)

// Lokalizacja VU
#define VU_X 400
#define VU_Y 125

// Lokalizacja Przycisków (odsunięte od VU)
#define BTN_X 10
#define BTN_Y 280


class RadioGUI {
private:
    TFT_eSPI* tft;
    TFT_eSprite vuSpr;   // Ten już masz
    TFT_eSprite wifiSpr; // DOPISZ TĘ LINIĘ TUTAJ
    uint16_t lastLevels; // DODAJ TO: Pamięć ostatnich poziomów dla animacji
public:


void updateStationName(String data) {
    // 1. Czyścimy obszar pod tekst (czarny prostokąt na górze)
    tft->fillRect(0, 0, 240, 60, TFT_BLACK); 
    
    // 2. Ustawienia tekstu
    tft->setTextColor(COL_GOLD);
    tft->setTextDatum(CC_DATUM); // Centrowanie
    
    // Wybierz czcionkę (używam 4 dla czytelności, możesz zmienić na swoją)
    int fontNum = 4; 
    
    // 3. Wyświetlamy tekst (centrowany na 120px szerokości, 30px od góry)
    tft->drawString(data, 120, 30, fontNum);
    
    Serial.println(">>> GUI: Nazwa zaktualizowana na ekranie");
}


void GUI::searchAndDraw(String query) {
    // 1. Czyszczenie zapytania (usuwanie zbędnych znaków)
    query.replace(" ", "+");
    query.replace("&", "");
    
    String url = "http://itunes.apple.com/search?term=" + query + "&media=music&limit=1";
    
    Serial.println(">>> SZUKANIE OKŁADKI: " + url);
    
    HTTPClient http;
    http.begin(url);
    int httpCode = http.GET();
    
    bool success = false;
    String imgUrl = "";

    if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        // Szukamy pola "artworkUrl100" w formacie JSON (bez ciężkich bibliotek JSON)
        int idx = payload.indexOf("artworkUrl100");
        if (idx != -1) {
            int start = payload.indexOf("http", idx);
            int end = payload.indexOf("\"", start);
            imgUrl = payload.substring(start, end);
            imgUrl.replace("100x100bb", "300x300bb"); // Zwiększamy rozdzielczość
            success = true;
        }
    }
    http.end();

    if (success && imgUrl.length() > 10) {
        Serial.println(">>> ZNALEZIONO URL: " + imgUrl);
        // Próba pobrania i narysowania (funkcja drawAlbumArt zapisuje na LittleFS)
        if (!drawAlbumArt(imgUrl)) {
            Serial.println(">>> Błąd pobierania, ładuję ikonę domyślną.");
            drawDefaultIcon();
        }
    } else {
        Serial.println(">>> Nie znaleziono okładki w iTunes.");
        drawDefaultIcon();
    }
}

// Funkcja ładująca ikonę zastępczą z dysku
void GUI::drawDefaultIcon() {
    if (LittleFS.exists("/default_art.jpg")) {
        // Rysujemy Twój domyślny obrazek
        drawJpgFile(LittleFS, "/default_art.jpg", 10, 50); 
    } else {
        // Jeśli nawet ikony nie ma, rysujemy np. pusty prostokąt
        tft.fillRect(10, 50, 200, 200, TFT_BLACK);
        tft.drawRect(10, 50, 200, 200, TFT_WHITE);
        tft.setCursor(50, 140);
        tft.print("BRAK OKLADKI");
    }
}
    
//-----------------------------------------------------------------------------

void updateDefaultIcon() {
    // Używamy -> ponieważ tft to wskaźnik
    tft->fillScreen(TFT_BLACK);
    tft->setTextColor(COL_GOLD);
    tft->drawCentreString("AKTUALIZACJA IKONY...", 120, 140, 2);

    HTTPClient http;
    http.begin("https://i.ibb.co/Y4r0Yz7n/default.jpg"); 
    
    int httpCode = http.GET();
    if (httpCode == 200) {
        File f = LittleFS.open("/default.jpg", "w");
        if (f) {
            http.writeToStream(&f);
            f.close();
            Serial.println(">>> Ikona zapisana pomyślnie!");
            tft->drawCentreString("GOTOWE!", 120, 160, 2);
        }
    } else {
        Serial.printf(">>> Błąd pobierania: %d\n", httpCode);
    }
    http.end();
    delay(1000);
}
    
    
  void checkAndPrepareDefaultIcon() {
    if (!LittleFS.begin(true)) {
        Serial.println("Błąd LittleFS!");
        return;
    }

    if (!LittleFS.exists("/default.jpg")) {
        Serial.println(">>> Ikona domyślna nieobecna. Pobieram raz na zawsze...");
        
        HTTPClient http;
        http.begin("https://i.ibb.co/Y4r0Yz7n/default.jpg");
        
        int httpCode = http.GET();
        if (httpCode == 200) {
            File f = LittleFS.open("/default.jpg", "w");
            if (f) {
                http.writeToStream(&f);
                f.close();
                Serial.println(">>> Ikona pobrana i zapisana w Flash!");
            }
        }
        http.end();
    } else {
        Serial.println(">>> Ikona domyślna jest już w pamięci. Gotowa do użycia.");
    }
}  
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    // Musimy też dodać wifiSpr do konstruktora, żeby wiedział o ekranie tft
    RadioGUI(TFT_eSPI* _tft) : tft(_tft), vuSpr(_tft), wifiSpr(_tft) {}

    void initSprites() {
        vuSpr.createSprite(70, 150); 
        wifiSpr.createSprite(30, 30); // Mały kwadrat na ikonę WiFi
    }
    
    // Ta funkcja musi być TUTAJ (wewnątrz klasy)
    
    void initVUSprite() {
        vuSpr.createSprite(65, 145); 
    }

    // Rysowanie WIFI
    void drawWifiIcon(int x, int y, uint16_t color) {
        wifiSpr.fillSprite(COL_BG); // Czyścimy tło

        // Rysujemy 3 segmenty (klocki) o różnej szerokości
        // Najniższy (kropka/mały klocek)
        wifiSpr.fillRect(12, 22, 6, 4, color); 
        
        // Środkowy łuk (segmentowy)
        wifiSpr.fillRect(7, 14, 16, 3, color); // Pozioma belka
        wifiSpr.fillRect(7, 17, 3, 3, color);  // Lewy "nóżka"
        wifiSpr.fillRect(20, 17, 3, 3, color); // Prawa "nóżka"

        // Górny łuk (segmentowy)
        wifiSpr.fillRect(2, 6, 26, 3, color);  // Pozioma belka
        wifiSpr.fillRect(2, 9, 3, 4, color);   // Lewa
        wifiSpr.fillRect(25, 9, 3, 4, color);  // Prawa

        wifiSpr.pushSprite(x, y);
    }


    // Punkt 2: Ikony od prawej: WiFi, potem Zegar

/*
void drawHeader(String stName, String timeStr, int wifiStatus) {
    // Nie czyścimy całego ekranu, tylko tam gdzie tekst się zmienia
    tft->fillRect(100, 10, 250, 40, COL_BG); // Pole nazwy stacji
    tft->fillRect(360, 10, 80, 40, COL_BG);  // Pole zegara

    tft->setTextColor(COL_GOLD); tft->drawString("Radio:", 15, 15, 4);
    tft->setTextColor(COL_TEXT); tft->drawString(stName, 100, 15, 4);
    tft->drawFastHLine(10, 52, 460, COL_GOLD);

    // Logika koloru
    uint16_t wifiColor;
    if (wifiStatus == 2) wifiColor = 0x07E0;      // Zielony (OK)
    else if (wifiStatus == 0) wifiColor = 0xF800; // Czerwony (Brak)
    else { // Status 1 - Miganie
        wifiColor = ((millis() / 500) % 2) ? 0x07E0 : 0x4208; // Zielony / Ciemnoszary
    }

    drawWifiIcon(440, 15, wifiColor);

    // Zegar
    tft->setTextColor(COL_CYAN);
    tft->setTextDatum(TR_DATUM); 
    tft->drawString(timeStr, 435, 15, 4);
    tft->setTextDatum(TL_DATUM);
}*/

void drawHeader(String stName, String timeStr, int wifiStatus) {
    // 1. Czyścimy strefę tekstu (kończymy na 395, by nie dotknąć VU)
    tft->fillRect(0, 0, 395, 52, COL_BG); 
    
    // 2. Czyścimy strefę System Info (nad VU)
    tft->fillRect(400, 0, 80, 52, COL_BG);

    // 3. Rysujemy elementy
    tft->setTextColor(COL_GOLD);
    tft->drawString("Radio:", 15, 15, 4);
    tft->setTextColor(COL_TEXT);
    tft->drawString(stName, 100, 15, 4);
    // Linia złota ma miec 460 szerokosci
    tft->drawFastHLine(10, 52, 460, COL_GOLD);

    // WiFi i Zegar (System Info)
    uint16_t wifiColor = (wifiStatus == 2) ? COL_LED_GN : COL_LED_RD;
    drawWifiIcon(445, 12, wifiColor); // Ikona w narożniku
    
    tft->setTextColor(COL_CYAN);
    tft->setTextDatum(TR_DATUM);
    tft->drawString(timeStr, 440, 15, 4); // Zegar obok ikony
}

void drawButtons() {
    // Używamy BTN_Y, żeby przyciski nie wchodziły na ramkę VU
    tft->fillRoundRect(20,  BTN_Y, 70, 35, 8, COL_PANEL); // PREV
    tft->fillRoundRect(110, BTN_Y, 70, 35, 8, COL_PANEL); // PLAY
    tft->fillRoundRect(200, BTN_Y, 70, 35, 8, COL_PANEL); // NEXT
}




// Punkt 1: Naprawa wyświetlania VU
void drawStereoVU(uint16_t levels, bool isRunning) {
    lastLevels = levels;
    // 1. Czyścimy bufor tłem panelu
    vuSpr.fillSprite(COL_PANEL); 

    // 2. DORYSOWUJEMY SKALĘ (napisy) WEWNĄTRZ BUFORA
    // Współrzędne są teraz relatywne do Sprite'a (X: 0-65, Y: 0-145)
    vuSpr.setTextColor(COL_SILVER, COL_PANEL);
    vuSpr.setTextDatum(MC_DATUM);
 
    // Rysujemy napisy na środku Sprite'a (x=32)
    vuSpr.drawString("+6",  32, 12,  1); 
    int yOff = 12; // ZMIENNA KOREKCYJNA - zmień tę wartość, aby przesunąć całą skalę góra/dół
  
    // Teraz każda pozycja Y jest obliczana względem yOff
    vuSpr.drawString("+6",  32, yOff + 0,   1);
    vuSpr.drawString("+3",  32, yOff + 15,  1);
    vuSpr.drawString(" -0-",   32, yOff + 30,  1);
    vuSpr.drawString("-3",  32, yOff + 45,  1);
    vuSpr.drawString("-6",  32, yOff + 60,  1);
    vuSpr.drawString("-10", 32, yOff + 75,  1);
    vuSpr.drawString("-15", 32, yOff + 90,  1);
    vuSpr.drawString("-20", 32, yOff + 105, 1);
    vuSpr.drawString("-40", 32, yOff + 120, 1);
    vuSpr.setTextDatum(TL_DATUM);


// 3. OBLICZAMY POZIOMY I DODAJEMY WZMOCNIENIE (GAIN)
    // Pobieramy surowe wartości
    int rawL = levels >> 8; 
    int rawR = levels & 0xFF;

    // DODAJ WZMOCNIENIE: np. mnożymy przez 1.5 lub 2.0
    // Możesz regulować tę wartość, aż przy głośnym utworze "0" będzie skakać na pomarańczowo
    float gain = 2.5; 
    
    uint8_t L = constrain(rawL * gain, 0, 255);
    uint8_t R = constrain(rawR * gain, 0, 255);

    // 4. RYSUJEMY DIODY
    for (int i = 0; i < 15; i++) {
        // Próg dla każdej diody (15 diod * 17 = 255)
        int th = i * 17; 
        uint16_t color = (i < 7) ? COL_LED_GN : (i < 10 ? COL_LED_YL : COL_LED_RD);
        int yP = 130 - (i * 9); 

        vuSpr.fillRect(2, yP, 18, 7, (isRunning && L > th) ? color : COL_LED_OFF);
        vuSpr.fillRect(44, yP, 18, 7, (isRunning && R > th) ? color : COL_LED_OFF);
    }

    vuSpr.pushSprite(VU_X + 4, VU_Y + 39);

/*



    // 3. OBLICZAMY POZIOMY
    uint8_t L = levels >> 8; 
    uint8_t R = levels & 0xFF;

    // 4. RYSUJEMY DIODY PO BOKACH NAPISÓW
    for (int i = 0; i < 15; i++) {
        int th = i * 17;
        uint16_t color = (i < 9) ? COL_LED_GN : (i < 13 ? COL_LED_YL : COL_LED_RD);
        int yP = 130 - (i * 9); 

        // Lewy słupek (po lewej stronie napisów)
        vuSpr.fillRect(3, yP, 18, 7, (isRunning && L > th) ? color : COL_LED_OFF);
        
        // Prawy słupek (po prawej stronie napisów)
        vuSpr.fillRect(45, yP, 18, 7, (isRunning && R > th) ? color : COL_LED_OFF);
    }

    // 5. WYPYCHAMY CAŁOŚĆ NA EKRAN (teraz napisy są bezpieczne w środku)
    vuSpr.pushSprite(VU_X + 4, VU_Y + 40);*/
}    


// Punkt 1, 6 i 7: Ramka VU, Skala 9-punktowa i Stereo/Mono
  
  /*
    void drawVUFrame() {
        tft->fillRoundRect(VU_X, VU_Y, 75, 193, 10, COL_PANEL);
        tft->drawRoundRect(VU_X, VU_Y, 75, 193, 10, COL_GOLD);
        
        // Punkt 6: Napis Stereo/Mono NAD skalą (wewnątrz ramki)
      //  tft->setTextColor(COL_GOLD, COL_PANEL);
    //    tft->setTextDatum(MC_DATUM);
        tft->setTextColor(COL_GOLD, COL_PANEL);
        tft->setTextDatum(MC_DATUM);
        tft->drawString("-----", VU_X + 37, VU_Y + 15, 1); // Górna linia (tryb)
        tft->setTextColor(COL_LGRAY, COL_PANEL);
        tft->drawString("--- kbps", VU_X + 37, VU_Y + 28, 1); // Dolna linia (bitrate)

        // Punkt 7: Skala 9 punktów (-40 do +6dB)
        tft->setTextColor(COL_SILVER, COL_PANEL);
        int y_start = VU_Y + 38;
        tft->drawString("+6",  VU_X + 37, y_start, 1);
        tft->drawString("+3",  VU_X + 37, y_start + 15, 1);
        tft->drawString(" -0-",   VU_X + 37, y_start + 30, 1);
        tft->drawString("-3",  VU_X + 37, y_start + 45, 1);
        tft->drawString("-6",  VU_X + 37, y_start + 60, 1);
        tft->drawString("-10", VU_X + 37, y_start + 75, 1);
        tft->drawString("-15", VU_X + 37, y_start + 90, 1);
        tft->drawString("-20", VU_X + 37, y_start + 105, 1);
        tft->drawString("-40", VU_X + 37, y_start + 125, 1);
        tft->setTextDatum(TL_DATUM);
    }
*/

void drawVUFrame() {
    // Rysujemy tylko ramkę i tło panelu
    tft->fillRoundRect(VU_X-2, VU_Y, 77, 193, 10, COL_PANEL);
    tft->drawRoundRect(VU_X-2, VU_Y, 77, 193, 10, COL_GOLD);
    
    // Napisy Stereo i Bitrate (zostają, bo są nad Spritem)
    tft->setTextColor(COL_GOLD, COL_PANEL);
    tft->setTextDatum(MC_DATUM);
    tft->drawString("-----", VU_X + 37, VU_Y + 15, 1);
    tft->setTextColor(COL_LGRAY, COL_PANEL);
    tft->drawString("--- kbps", VU_X + 37, VU_Y + 28, 1);

    // TUTAJ USUNĄŁEM CAŁY "PUNKT 7" (wszystkie tft->drawString ze skalą)
    tft->setTextDatum(TL_DATUM);
}


// Podmień lub zaktualizuj tę funkcję w klasie RadioGUI
void updateAudioInfo(int channels, uint32_t bitrate) {
    tft->setTextDatum(MC_DATUM);
    
    // 1. Obsługa Stereo/Mono (Górny napis)
    tft->setTextColor(COL_LED_GN, COL_PANEL);
    String mode = (channels == 2) ? "STEREO" : "MONO";
    tft->fillRect(VU_X + 10, VU_Y + 8, 55, 12, COL_PANEL); // Czyści pole trybu
    tft->drawString(mode, VU_X + 37, VU_Y + 15, 1);

    // 2. Obsługa Bitrate (Napis pod Stereo/Mono)
    // Używamy np. jasnoszarego (COL_LGRAY) dla kontrastu
    tft->setTextColor(0xD69A, COL_PANEL); 
    tft->fillRect(VU_X + 10, VU_Y + 22, 55, 12, COL_PANEL); // Czyści pole bitrate
    
    String bitStr = String(bitrate / 1000) + " kbps";
    tft->drawString(bitStr, VU_X + 37, VU_Y + 28, 1);
    
    tft->setTextDatum(TL_DATUM);
}

#include <WiFiClientSecure.h> // Upewnij się, że to jest na samej górze pliku!
//----------------------------rysowanie obrazka albumu------------------------------------------------------
void drawAlbumArt(String url) {
    if (url.length() < 10) return;

    Serial.println(">>> Pobieranie okładki: " + url);

    // 1. Przygotowanie połączenia
    NetworkClientSecure client;
    client.setInsecure(); 
    HTTPClient http;
    http.setTimeout(5000); 

    if (http.begin(client, url)) {
        int httpCode = http.GET();
        if (httpCode == HTTP_CODE_OK) {
            int len = http.getSize();
            
            if (len > 0 && len < 150000) { // Zabezpieczenie RAM (max 150KB)
                uint8_t* jpgBuffer = (uint8_t*)malloc(len);
                if (jpgBuffer) {
                    WiFiClient* stream = http.getStreamPtr();
                    int downloaded = 0;
                    unsigned long startTime = millis();

                    // 2. Pętla pobierania odporna na wolne WiFi
                    while (downloaded < len && (millis() - startTime < 5000)) {
                        if (stream->available()) {
                            int n = stream->readBytes(jpgBuffer + downloaded, len - downloaded);
                            downloaded += n;
                            startTime = millis(); // Resetujemy licznik czasu po odebraniu danych
                        }
                        // Kluczowe: audio musi grać w tle!
                        //audio.loop(); 
                    }

                    Serial.printf("Pobrano: %d z %d bajtów\n", downloaded, len);

                    if (downloaded >= len) {
                        // 3. Czyszczenie tła i rysowanie
                        tft->fillRect(20, 70, 200, 200, COL_BG); 
                        TJpgDec.setJpgScale(1);
                        TJpgDec.drawJpg(20, 70, jpgBuffer, len);
                        Serial.println("Sukces: Obrazek na ekranie.");
                    } else {
                        Serial.println("BŁĄD: Timeout - nie pobrano całości danych.");
                    }
                    free(jpgBuffer); 
                } else {
                    Serial.println("BŁĄD: Brak pamięci RAM!");
                }
            }
        } else {
            Serial.printf("BŁĄD HTTP: %d\n", httpCode);
        }
        http.end();
    }

    // 4. Odświeżenie złotej ramki
    tft->drawRect(19, 69, 202, 202, 0xD6BA); // COL_GOLD
    tft->drawRect(18, 68, 204, 204, 0xD6BA); 
}

//------------------------------------------------------------------------------------------------------------------

    // Pozwalamy funkcji zewnętrznej (callback) odświeżyć VU
    void refreshVUFromCallback() {
        this->drawStereoVU(lastLevels, true);
    }


    
};
#endif