#ifndef METER_H_
#define METER_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"

/**
 * @brief Grid energy meter model
 */
typedef enum {
    ENERGY_METER_NONE,
    ENERGY_METER_ORNO_515,
    ENERGY_METER_ORNO_517,
} meter_model_t;

/**
 * @brief Estrutura com os dados de medição trifásica.
 */
typedef struct MeterData
{
    float vrmsA;
    float vrmsB;
    float vrmsC;
    float irmsA;
    float irmsB;
    float irmsC;
    int32_t wattA;
    int32_t varA;
    int32_t vaA;
    int32_t wattB;
    int32_t varB;
    int32_t vaB;
    int32_t wattC;
    int32_t varC;
    int32_t vaC;
} MeterData;

/**
 * @brief Inicializa o hardware do medidor e recursos internos (SPI, mutex).
 */
void meter_init(void);

/**
 * @brief Inicia a task de medição.
 */
void meter_start(void);

/**
 * @brief Para a task de medição e reseta dados.
 */
void meter_stop(void);

/**
 * @brief Zera todos os campos da estrutura de dados do medidor.
 */
void meter_initData(void);

/**
 * @brief Retorna uma cópia segura dos dados atuais do medidor.
 * 
 * @return MeterData Cópia da última leitura válida.
 */
MeterData meter_getData(void);


/**
 * @brief Check if meter task is currently running.
 * 
 * @return true if running, false otherwise.
 */
bool meter_is_running(void);

// High level energy meter API
void energy_meter_init(void);
bool meter_get_state(void);
esp_err_t meter_set_state(bool _state);
meter_model_t meter_get_model(void);
esp_err_t meter_set_model(meter_model_t mode);
void energy_meter_start_session(void);
void energy_meter_stop_session(void);
void energy_meter_process(bool charging, uint16_t charging_current);
uint32_t energy_meter_get_power(void);
uint32_t energy_meter_get_session_time(void);
uint32_t energy_meter_get_charging_time(void);
uint32_t energy_meter_get_consumption(void);
void energy_meter_get_voltage(float *voltage);
float energy_meter_get_l1_voltage(void);
float energy_meter_get_l2_voltage(void);
float energy_meter_get_l3_voltage(void);
void energy_meter_get_current(float *current);
float energy_meter_get_l1_current(void);
float energy_meter_get_l2_current(void);
float energy_meter_get_l3_current(void);
const char *meter_model_to_str(meter_model_t mode);
meter_model_t meter_str_to_model(const char *str);
const char *meter_state_to_str(bool state);
bool meter_str_to_state(const char *str);

#ifdef __cplusplus
}
#endif

#endif /* METER_H_ */