#include "display.hpp"
#include "config.hpp"
#include "logger.h"

extern logging::Logger logger;

// Constructor to initialize the display with I2C parameters
Display::Display()
    : display(DISPLAY_ADDRESS, DISPLAY_SDA, DISPLAY_SCL)
{
}

void Display::setup_display()
{
    pinMode(16, OUTPUT);
    digitalWrite(16, LOW); // set GPIO16 low to reset OLED
    delay(50);
    digitalWrite(16, HIGH);
    if (!display.init())
    {

        logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "DISPLAY", "Display initialization failed!");
        return;
    }
    display.flipScreenVertically();
    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_LEFT);

    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "Display init done!");
}

void Display::display_toggle(bool toggle)
{
    displayOn = toggle;
    if (displayOn)
    {
        display.displayOn();
    }
    else
    {
        display.displayOff();
    }
}

void Display::cleanTFT()
{
    display.clear();
    display.display();
    display.setFont(ArialMT_Plain_10);
}
void Display::show_display(String header, int wait)
{
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "One line: %s", header.c_str());
    cleanTFT();
    display.setFont(ArialMT_Plain_24);
    display.drawString(0, 20, header);
    display.display();
    delay(wait);
}

void Display::show_display(String header, String line1, int wait)
{
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "Two lines: \n %s,  \n %s", header.c_str(), line1.c_str());
    cleanTFT();
    display.setFont(ArialMT_Plain_16);
    display.drawString(0, 0, header);
    display.drawString(0, 18, line1);
    display.display();
    delay(wait);
}

void Display::show_display(String header, String line1, String line2, int wait)
{
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "Three lines: %s, %s, %s", header.c_str(), line1.c_str(), line2.c_str());
    cleanTFT();
    display.drawString(0, 0, header);
    display.drawString(0, 12, line1);
    display.drawString(0, 24, line2);
    display.display();
    delay(wait);
}

void Display::show_display(String header, String line1, String line2, String line3, int wait)
{
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "Four lines: %s, %s, %s, %s", header.c_str(), line1.c_str(), line2.c_str(), line3.c_str());
    cleanTFT();
    display.drawString(0, 0, header);
    display.drawString(0, 12, line1);
    display.drawString(0, 24, line2);
    display.drawString(0, 36, line3);
    display.display();
    delay(wait);
}

void Display::show_display(String header, String line1, String line2, String line3, String line4, int wait)
{
    
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "Five lines: %s, %s, %s, %s, %s", header.c_str(), line1.c_str(), line2.c_str(), line3.c_str(), line4.c_str());
    cleanTFT();
    display.drawString(0, 0, header);
    display.drawString(0, 12, line1);
    display.drawString(0, 24, line2);
    display.drawString(0, 36, line3);
    display.drawString(0, 48, line4);
    display.display();
    delay(wait);
}

void Display::show_message(const char *message, int line, int wait)
{
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "DISPLAY", "Line %d: %s", line, message);
    
    display.setFont(ArialMT_Plain_10);

    // Set cursor position based on line number (optional)
    if (line >= 0 || line <= 5)
    {
        display.drawString(0, line * 13, message);
    }

    // Display the updated content
    display.display();

    delay(wait); // Convert wait time to milliseconds
}
