#pragma once

#include "main.h"
#include <string.h>
#include "charger_control.h"
#include "isr_opt.h"

// Команды от ПК к устройству
// Пакет статуса изоляции от отдельного блока по одностороннему UART
#define CMD_ISOLATION_STATUS     0x01

#define CMD_GET_STATUS          0x40

#define CMD_GET_LOG             0x50
#define CMD_GET_LOG_CONTINUE    0x51
#define CMD_GET_INFO            0x60

// Команды с аргументами
#define CMD_SET_POWER_LIMIT     0xC0
#define CMD_TEST_PSU            0xC1
#define CMD_CHARGE_PERMIT       0xC2

// Сервисные команды
#define CMD_SET_CONFIG          0xB0

// Перезагрузка для входа в бутлоадер
#define CMD_DEVICE_RESET		0xB5
// Пожарная тревога (внешний триггер)
#define CMD_FIRE_ALARM			0xB7

// Коды ответов
#define RESP_SUCCESS    		0x12
#define RESP_FAILED     		0x13
#define RESP_INVALID    		0x14

// Максимальный размер буфера полезной нагрузки (включая 4 байта CRC)
#define MAX_TX_BUFFER_SIZE 256
// Максимальный размер буфера для принятого экранированного пакета без START/END
#define MAX_RX_BUFFER_SIZE 256

// Макросы для CRC
#define SERIAL_PROTOCOL_CRC_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\
                                        tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\
                                        UNUSED(tmpreg); \
                                      } while(0)

#define SERIAL_PROTOCOL_CRC_CLK_DISABLE()       (RCC->AHBENR &= ~(RCC_AHBENR_CRCEN))

#define CRC32_POLYNOMIAL                        ((uint32_t)0xEDB88320)

void ReadVersion();

// Структура для хранения принятой команды с аргументом
typedef struct {
    uint8_t command;
    uint8_t argument_length;
    void* argument;
} ReceivedCommand_t;

typedef enum {
    SC_SOURCE_UART2 = 0,
    SC_SOURCE_UART5 = 1,
} SC_Source_t;

typedef struct __attribute__((packed)) {
    uint8_t isolationStatus;
    uint16_t isolationResistance;
    int16_t voltageHigh;
    int16_t voltageLow;
    int16_t voltageComm;
} IsolationStatusPacket_t;

typedef struct __attribute__((packed)) {

	CONN_State_t connState;
    CONN_Error_t chargingError; // Причина остановки зарядки
	uint8_t SOC; // State of charge [%] 
	uint32_t Energy; // Energy [Wh]    
	uint16_t RequestedVoltage; //1V/bit
	uint16_t RequestedCurrent; //0.1A/bit
	uint16_t MeasuredVoltage;  //1V/bit
	uint16_t MeasuredCurrent;  //0.1A/bit
	uint8_t  outputEnabled;
	uint16_t chargingElapsedTimeMin;
	uint8_t chargingElapsedTimeSec;
    uint16_t estimatedRemainingChargingTime;

    // Flags (32 bit)
    uint8_t relayAC:1;
    uint8_t relayDC:1;
    uint8_t relayAUX:1;
    uint8_t lockState:1;
    uint8_t stopButton:1;
    uint8_t logAvailable:1;
    uint8_t evInfoAvailable:1;
    uint8_t psuOnline:1;
    uint8_t rsvd1[3];

    int8_t tempConnector0;
    int8_t tempConnector1;
    int8_t tempAmbient;
    int8_t tempBatteryMax;
    int8_t tempBatteryMin;

    uint16_t highestVoltageOfBatteryCell;
    uint8_t batteryStatus;

    uint16_t phaseVoltageAB;
    uint16_t phaseVoltageBC;
    uint16_t phaseVoltageCA;
    
    char VIN[17];

	uint8_t batteryType;		//battery type
	uint16_t batteryCapacity; 	// 0.1Ah/bit
	uint16_t batteryVoltage;  	// 0.1V/bit
	uint8_t batteryVendor[4]; 	// Battery vendor (ASCII string)
	uint32_t batterySN;			// int
	uint8_t batteryManuY;		// year (offset 1985)
	uint8_t batteryManuM;		// month
	uint8_t batteryManuD;		// day
	uint16_t batteryCycleCount;
	uint8_t ownAuto;			// 0 = lizing, 1 = own auto
	uint8_t EV_SW_VER[8];

    uint8_t testMode;
    uint16_t testVoltage;
    uint16_t testCurrent;

} StatusPacket_t;

typedef struct __attribute__((packed)) {
    uint16_t serialNumber;
    uint8_t boardVersion;
    uint8_t stationType;
    uint16_t fw_version_major;
    uint16_t fw_version_minor;
    uint16_t fw_version_patch;
} InfoPacket_t;

typedef struct __attribute__((packed)) {
    char location[3];
    uint32_t chargerNumber;
    uint32_t unixTime;

} ConfigBlock_t;

// Предварительное объявление структуры протокола
typedef struct SerialControl_t SerialControl_t;

// Структура протокола
struct SerialControl_t {
    // Буферы для UART
    uint8_t tx_buffer[MAX_TX_BUFFER_SIZE];
    uint8_t rx_buffer[MAX_RX_BUFFER_SIZE];

    // Переменные для передачи команды
    volatile ReceivedCommand_t received_command;
    volatile uint8_t command_ready;

    // Время отправки последнего пакета
    volatile uint32_t tx_tick;

};

// Публичные методы
void SC_Init();
void SC_Task();
ISR_FAST void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code);
void SC_RecoverUartDma(UART_HandleTypeDef *huart);

// Внешняя функция обработки команд (определена в serial_handler.c)
extern void SC_CommandHandler(ReceivedCommand_t* cmd);

extern SerialControl_t serial_control;
extern StatusPacket_t statusPacket;
extern InfoPacket_t infoPacket;
extern IsolationStatusPacket_t ISO;
extern volatile SC_Source_t g_sc_command_source;
