#include "low_level_display_st7789.h"
#include <stdio.h>
#include <stdlib.h>

// Note: This is a placeholder implementation
// You'll need to add the actual ST7789 driver code to lib/st7789/

LowLevelDisplayST7789::LowLevelDisplayST7789(const st7789_config* cfg, int w, int h)
    : config(cfg), width(w), height(h), initialized(false), rgb_buffer(nullptr) {
}

LowLevelDisplayST7789::~LowLevelDisplayST7789() {
    if (rgb_buffer) {
        free(rgb_buffer);
        rgb_buffer = nullptr;
    }
}

bool LowLevelDisplayST7789::init() {
    if (initialized) {
        return true;
    }
    
    // TODO: Implement ST7789 initialization
    // st7789_init(config, width, height);
    // 
    // TODO: Allocate RGB565 buffer once (reused for all draw operations)
    // size_t buffer_size = width * height * sizeof(uint16_t);
    // rgb_buffer = (uint16_t *)malloc(buffer_size);
    // if (!rgb_buffer) {
    //     printf("Error: Failed to allocate %zu bytes for RGB buffer\n", buffer_size);
    //     return false;
    // }
    
    printf("ST7789 display initialized: %dx%d (stub)\n", width, height);
    initialized = true;
    return false;  // Return false until actual driver is implemented
}

void LowLevelDisplayST7789::clear(bool white) {
    // TODO: Implement
    (void)white;
}

void LowLevelDisplayST7789::draw_pixel(int x, int y, bool white) {
    // TODO: Implement
    (void)x; (void)y; (void)white;
}

void LowLevelDisplayST7789::draw_buffer(const uint8_t* bit_buffer) {
    // TODO: Implement - convert 1-bit to RGB565 and write
    // IMPORTANT: Use the persistent rgb_buffer member, NOT malloc/free!
    // Example:
    //   if (!bit_buffer || !rgb_buffer) return;
    //   for (int y = 0; y < height; y++) {
    //       for (int x = 0; x < width; x++) {
    //           int byte_index = (y * width + x) / 8;
    //           int bit_index = 7 - (x % 8);
    //           bool pixel_white = (bit_buffer[byte_index] >> bit_index) & 0x01;
    //           rgb_buffer[y * width + x] = pixel_white ? COLOR_WHITE : COLOR_BLACK;
    //       }
    //   }
    //   st7789_write(rgb_buffer, width * height);
    (void)bit_buffer;
}

void LowLevelDisplayST7789::refresh() {
    // ST7789 updates immediately
}

void LowLevelDisplayST7789::set_backlight(bool on) {
    set_brightness(on ? 100 : 0);
}

void LowLevelDisplayST7789::set_brightness(uint8_t brightness) {
    st7789_set_brightness(brightness);
}

uint8_t LowLevelDisplayST7789::get_brightness() const {
    return st7789_get_brightness();
}

void LowLevelDisplayST7789::set_rotation(uint8_t rotation) {
    // TODO: Implement
    (void)rotation;
}

void LowLevelDisplayST7789::on_idle_2min() {
    if (!is_dimmed && !is_sleeping) {
        saved_brightness = get_brightness();
        set_brightness(5); // Dim to 5%
        is_dimmed = true;
        printf("ST7789: Dimmed to 5%%\n");
    }
}

void LowLevelDisplayST7789::on_idle_10min() {
    if (!is_sleeping) {
        st7789_sleep();
        is_sleeping = true;
        is_dimmed = true; // Sleep implies dimmed
        printf("ST7789: Entered sleep mode\n");
    }
}

void LowLevelDisplayST7789::on_user_interaction() {
    if (is_sleeping) {
        st7789_wake();
        // Restore brightness if we have a saved value, or default to 100
        set_brightness(saved_brightness > 0 ? saved_brightness : 100);
        is_sleeping = false;
        is_dimmed = false;
        printf("ST7789: Woke from sleep\n");
    } else if (is_dimmed) {
        set_brightness(saved_brightness > 0 ? saved_brightness : 100);
        is_dimmed = false;
        printf("ST7789: Restored brightness\n");
    }
}
