#include "power.h"
#include "char_lcd.h"
#include "starcode.h"
#include <esp_log.h>

static const char* TAG = "power";

void bat_monitor_task(void* arg) {
    while (1) {
        char str_buf[33] = {0};
        uint16_t voltage = lipo.voltage();
        sprintf(str_buf, "%d.%03dV", voltage / 1000, voltage % 1000);

        lcd_clear();
        lcd_print(0, 1, str_buf);

        int16_t current = lipo.current();
        sprintf(str_buf, "%dmA", current);

        lcd_print(1, 1, str_buf);


        int16_t total_cap = lipo.capacity(capacity_measure::FULL);
        sprintf(str_buf, "%dmAh", total_cap);

        lcd_print(2, 1, str_buf);

        int16_t soc = lipo.soc(soc_measure::FILTERED);
        sprintf(str_buf, "%d%%", soc);

        lcd_print(3, 1, str_buf);


        vTaskDelay(pdMS_TO_TICKS(250));
    }
    
    vTaskDelete(NULL);
}

void init_power_board() {
    ESP_LOGI(TAG, "Initializing power board...");

    if (!lipo.begin()) {
        ESP_LOGE(TAG, "Failed to init communication with the battery gas guage");
        return;
    }

    auto voltage = lipo.voltage();
    ESP_LOGI(TAG, "Battery Voltage: %d", voltage);

    ESP_LOGI(TAG, "Power board initialized!");
}

uint16_t get_bat_voltage() {
    return lipo.voltage();
}

void lcd_print_header_bat() {
    if (!lcd_header_enabled()) return;
    if (lcd_starcode_displaying_result()) return;
    
    uint8_t soc = lipo.soc();
    int16_t current = lipo.current();
    char buf[6];
    if (soc < 5 && current <= 0) {
        snprintf(buf, sizeof(buf), " LOW");
    } else if (soc == 100) {
        snprintf(buf, sizeof(buf), " 100");
    } else {
        if (current > 0) {
            snprintf(buf, sizeof(buf), " %2d+", soc);
        } else {
            snprintf(buf, sizeof(buf), " %2d%%", soc);
        }
    }

    lcd_print(0, 16, buf);
}
