/*
 * evse_session.c
 * Implementation of evse_session module using instantaneous power accumulation
 */
#include <inttypes.h>  // for PRIu32
#include "evse_session.h"
#include "evse_meter.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

static const char *TAG = "evse_session";

// Internal state
static TickType_t session_start_tick = 0;
static uint32_t   watt_seconds        = 0;  // accumulator of W·s
static evse_session_t last_session;
static bool            last_session_valid = false;

void evse_session_init(void) {
    session_start_tick   = 0;
    watt_seconds         = 0;
    last_session_valid   = false;
}

void evse_session_start(void) {
    session_start_tick = xTaskGetTickCount();
    watt_seconds       = 0;
    ESP_LOGI(TAG, "Session started at tick %u", (unsigned)session_start_tick);
}

void evse_session_end(void) {
    if (session_start_tick == 0) {
        ESP_LOGW(TAG, "evse_session_end called without active session");
        return;
    }
    TickType_t now = xTaskGetTickCount();
    uint32_t duration_s = (now - session_start_tick) / configTICK_RATE_HZ;
    uint32_t energy_wh = watt_seconds / 3600U;
    uint32_t avg_power = duration_s > 0 ? watt_seconds / duration_s : 0;

    last_session.start_tick  = session_start_tick;
    last_session.duration_s  = duration_s;
    last_session.energy_wh   = energy_wh;
    last_session.avg_power_w = avg_power;
    last_session.is_current  = false;
    last_session_valid       = true;

    session_start_tick = 0;
    ESP_LOGI(TAG, "Session ended: duration=%" PRIu32 " s, energy=%" PRIu32 " Wh, avg_power=%" PRIu32 " W",
            (uint32_t)duration_s, (uint32_t)energy_wh, (uint32_t)avg_power);
}

void evse_session_tick(void) {
    if (session_start_tick == 0) return;
    // Should be called every second (or known interval)
    uint32_t power_w = evse_meter_get_instant_power();
    watt_seconds += power_w;
}

bool evse_session_get(evse_session_t *out) {
    if (out == NULL) return false;

    if (session_start_tick != 0) {
        TickType_t now = xTaskGetTickCount();
        uint32_t duration_s = (now - session_start_tick) / configTICK_RATE_HZ;
        uint32_t energy_wh   = watt_seconds / 3600U;
        uint32_t avg_power   = duration_s > 0 ? watt_seconds / duration_s : 0;

        out->start_tick   = session_start_tick;
        out->duration_s   = duration_s;
        out->energy_wh    = energy_wh;
        out->avg_power_w  = avg_power;
        out->is_current   = true;
        return true;
    }

    if (last_session_valid) {
        *out = last_session;
        return true;
    }

    return false;
}
