#pragma once

#include "main.h"
#include "charger_control.h"
#include "usart.h"
#include "cp.h"

void CCS_SerialLoop(void);
void CCS_Init(void);
void CCS_SendEmergencyStop(void);
void CCS_SendStart(void);
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size);
void CCS_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);

typedef enum {
    CCS_UNKNOWN = 0,
    CCS_DISABLED = 1,
    CCS_UNPLUGGED = 2,
    CCS_AUTH_REQUIRED = 3,
    CCS_CONNECTED = 4,
    CCS_REPLUGGING = 5,
} CCS_ConnectorState_t;

typedef enum {
    PSU_OFF = 0,
    PSU_ON = 1,
    PSU_PREPARE = 2,
} EnablePSU_t;

typedef struct {
    uint16_t maxVoltage;
    uint16_t minVoltage;
    uint16_t maxCurrent;
    uint16_t minCurrent;
    uint32_t maxPower;
} CCS_MaxLoad_t;

/* Commands Everest -> module. */
#define CMD_E2M_PWM_DUTY            0x40
#define CMD_E2M_ENABLE_OUTPUT       0x41
#define CMD_E2M_RESET               0x42
#define CMD_E2M_ENABLE              0x43
#define CMD_E2M_REPLUG              0x44
#define CMD_E2M_SET_OUTPUT_VOLTAGE  0x45
#define CMD_E2M_ISOLATION_CONTROL   0x46
#define CMD_E2M_EV_INFO             0x47
#define CMD_E2M_EVSE_STATE          0x48
#define CMD_E2M_KEEP_ALIVE          0x49

/* Commands module -> Everest. */
#define CMD_M2E_STATE               0x50
#define CMD_M2E_RESET               0x52
#define CMD_M2E_ESTOP               0x53
#define CMD_M2E_START               0x54

typedef struct __attribute__((packed)) {
    uint8_t pwm_duty_percent;
} e2m_pwm_duty_t;

typedef struct __attribute__((packed)) {
    uint8_t enable_output;
} e2m_enable_output_t;

typedef struct __attribute__((packed)) {
    uint8_t reset;
} e2m_reset_t;

typedef struct __attribute__((packed)) {
    uint8_t enable;
} e2m_enable_t;

typedef struct __attribute__((packed)) {
    uint8_t replug;
} e2m_replug_t;

typedef struct __attribute__((packed)) {
    uint16_t voltage_V;
    uint16_t current_0p1A;
} e2m_set_output_t;

typedef struct __attribute__((packed)) {
    uint8_t command;
} e2m_isolation_control_t;

typedef struct __attribute__((packed)) {
    uint16_t valid_mask;
    uint16_t soc;
    uint16_t present_voltage;
    uint16_t present_current;
    uint16_t target_voltage;
    uint16_t target_current;
    uint16_t max_current;
    uint16_t min_current;
    uint16_t max_voltage;
    uint32_t max_power;
    uint32_t remaining_energy;
    uint16_t battery_capacity;
    uint16_t battery_full_soc;
    uint16_t battery_bulk_soc;
    uint32_t estimated_time_full;
    uint32_t departure_time;
    uint32_t estimated_time_bulk;
} CCS_EvInfo_t;

typedef struct __attribute__((packed)) {
    uint8_t DutyCycle;
    uint8_t OutputEnabled;
    uint16_t MeasuredVoltage;
    uint16_t MeasuredCurrent;
    uint32_t Power;
    uint32_t Energy;
    uint32_t IsolationResistance;
    uint8_t IsolationValid;
    uint8_t CpState;
    uint16_t MaxVoltage;
    uint16_t MinVoltage;
    uint16_t MaxCurrent;
    uint16_t MinCurrent;
    uint32_t MaxPower;
} CCS_State_t;

extern CCS_MaxLoad_t CCS_MaxLoad;
extern CCS_EvInfo_t CCS_EvInfo;
extern CONN_State_t CCS_EvseState;
extern uint8_t REPLUG;
