#include "serial_control.h"
#include "charger_gbt.h"
#include "crc.h"
#include "usart.h"
#include "charger_control.h"
#include "charger_gbt.h"
#include "board.h"
#include "psu_control.h"
#include "debug.h"

#ifdef USE_WEB_INTERFACE

extern uint8_t GBT_BAT_STAT_recv;

uint8_t config_initialized = 0;
ConfigBlock_t config = {
    .location = "RUS",
    .chargerNumber = 00001,
    .unixTime = 1721651966,
};

// Единая функция-обработчик всех команд со switch-case
void SC_CommandHandler(ReceivedCommand_t* cmd) {
    
    uint8_t response_code = RESP_FAILED;

    switch (cmd->command) {
        // Команды БЕЗ аргументов
        case CMD_GET_STATUS:
            // Логика получения информации
            monitoring_data_callback();

            // Отправляем с нормальным приоритетом
            SC_SendPacket((uint8_t*)&statusPacket, sizeof(statusPacket), CMD_GET_STATUS);
            return; // Специальный ответ уже отправлен

        case CMD_GET_INFO:
            SC_SendPacket((uint8_t*)&infoPacket, sizeof(infoPacket), CMD_GET_INFO);
            return;

        case CMD_GET_LOG:
            debug_buffer_send();
            return; // Ответ формируется внутри debug_buffer_send
            
        // Команды С аргументами

        case CMD_SET_CONFIG:
            if (cmd->argument_length == sizeof(ConfigBlock_t)) {
                memcpy(&config, cmd->argument, sizeof(ConfigBlock_t));
                GBT_SetConfig();
                config_initialized = 1;
                GBT_SetConfig();
//                CONN.connState = CONN_Available; //
                log_printf(LOG_INFO, "Set Config: %s %d\n", config.location, config.chargerNumber);
                response_code = RESP_SUCCESS;
                break;
            }
            response_code = RESP_FAILED;
            break;
        case CMD_SET_POWER_LIMIT:
            if (cmd->argument_length == 1) {
                PSU0.power_limit = ((uint8_t*)cmd->argument)[0] * 1000;
                log_printf(LOG_INFO, "Power limit: %d\n", PSU0.power_limit);
                //CONN.connState = (((uint8_t*)cmd->argument)[0])/4;
                response_code = RESP_SUCCESS;
                break;
            }
            response_code = RESP_FAILED;
            break;
        case CMD_CHARGE_PERMIT:
            if (cmd->argument_length == 1) {
                CONN.connControl = ((uint8_t*)cmd->argument)[0];
                log_printf(LOG_INFO, "Charge permit: %d\n", CONN.connControl);
                response_code = RESP_SUCCESS;
                break;
            }
            response_code = RESP_FAILED;
            break;

        case CMD_TEST_PSU:
            // if (cmd->argument_length == sizeof(PSU_TestMode_t)) {
            //     memcpy(&PSU_TestMode, cmd->argument, sizeof(PSU_TestMode_t));
            //     log_printf(LOG_INFO, "Test PSU: %d %d %d\n", PSU_TestMode.enable, PSU_TestMode.voltage, PSU_TestMode.current);
            //     response_code = RESP_SUCCESS;
            //     break;
            // }
            response_code = RESP_FAILED;
            break;
        case CMD_DEVICE_RESET:
            // 2. Отправляем SUCCESS (хост может успеть получить его перед ребутом)
            SC_SendPacket(NULL, 0, RESP_SUCCESS);

            while(huart2.gState == HAL_UART_STATE_BUSY_TX); // Ожидание завершения передачи
            // 3. Выполняем программный сброс
            NVIC_SystemReset();
            return; // Сюда код уже не дойдет, но для компилятора нужно
            
        default:
            // Неизвестная команда
            response_code = RESP_FAILED;
            break;
    }

    // Отправляем финальный ответ (для команд без собственного ответа)
    SC_SendPacket(NULL, 0, response_code);
}


// Колбэк для заполнения данных мониторинга
void monitoring_data_callback() {

    // Информация о зарядной сессии
	statusPacket.SOC = CONN.SOC;
	statusPacket.Energy = CONN.Energy;
	statusPacket.RequestedVoltage = CONN.RequestedVoltage;
	statusPacket.RequestedCurrent = CONN.WantedCurrent;
	statusPacket.MeasuredVoltage = CONN.MeasuredVoltage;
	statusPacket.MeasuredCurrent = CONN.MeasuredCurrent;
	statusPacket.outputEnabled = CONN.outputEnabled;
	statusPacket.chargingError = CONN.chargingError;
    statusPacket.connState = CONN.connState;
    statusPacket.chargingElapsedTimeMin = 0;
    statusPacket.chargingElapsedTimeSec = 0;
    statusPacket.estimatedRemainingChargingTime = 0;

    // состояние зарядной станции
    statusPacket.relayAC = RELAY_Read(RELAY_AC);
    statusPacket.relayDC = RELAY_Read(RELAY_DC);
    statusPacket.relayAUX = RELAY_Read(RELAY_AUX0);
    statusPacket.lockState = GBT_LockGetState();
    statusPacket.stopButton = !IN_ReadInput(IN_ESTOP);
    statusPacket.logAvailable = (debug_buffer_available()>0)?1:0;
    statusPacket.evInfoAvailable = GBT_BAT_STAT_recv;
    statusPacket.psuOnline = PSU0.online;

    statusPacket.tempConnector0 = GBT_ReadTemp(0); // температура коннектора
    statusPacket.tempConnector1 = GBT_ReadTemp(1);
    statusPacket.tempAmbient = PSU0.tempAmbient; // температура окружающего воздуха
    statusPacket.tempBatteryMax = GBT_BatteryStatus.batteryHighestTemp; // максимальная температура батареи
    statusPacket.tempBatteryMin = GBT_BatteryStatus.batteryLowestTemp; // минимальная температура батареи

    statusPacket.highestVoltageOfBatteryCell = GBT_ChargingStatus.highestVoltageOfBatteryCell;
    statusPacket.batteryStatus = GBT_BatteryStatus.batteryStatus;

    statusPacket.phaseVoltageAB = PSU_06.VAB;
    statusPacket.phaseVoltageBC = PSU_06.VBC;
    statusPacket.phaseVoltageCA = PSU_06.VCA;

    memcpy(statusPacket.VIN, GBT_EVInfo.EVIN, sizeof(GBT_EVInfo.EVIN));

    statusPacket.batteryType = GBT_EVInfo.batteryType;
	statusPacket.batteryCapacity = GBT_EVInfo.batteryCapacity;
	statusPacket.batteryVoltage = GBT_EVInfo.batteryVoltage;
	memcpy(statusPacket.batteryVendor, GBT_EVInfo.batteryVendor, sizeof(statusPacket.batteryVendor));
	statusPacket.batterySN = GBT_EVInfo.batterySN;
    statusPacket.batteryManuD = GBT_EVInfo.batteryManuD;
	statusPacket.batteryManuM = GBT_EVInfo.batteryManuM;
	statusPacket.batteryManuY = GBT_EVInfo.batteryManuY;
	statusPacket.batteryCycleCount = GBT_EVInfo.batteryCycleCount;
	statusPacket.ownAuto = GBT_EVInfo.ownAuto;
    memcpy(statusPacket.EV_SW_VER, GBT_EVInfo.EV_SW_VER, sizeof(statusPacket.EV_SW_VER));

    statusPacket.testMode = 0;
    statusPacket.testVoltage = 0;
    statusPacket.testCurrent = 0;

    // Информация о тачке

	// --- Информация об EV (из команды info2) ---
	// memcpy(statusPacket.version, GBT_EVInfo.version, sizeof(statusPacket.version));
	

	// --- Состояние Hardware и GBT (различные команды) ---
	//statusPacket.lockState = GBT_LockGetState(); // Из команды lock_state
	//statusPacket.ccState = CONN_CC_GetState();   // Из команды cc_state
	//statusPacket.ccAdc = CONN_CC_GetAdc();       // Из команды adc

	// --- Поля, требующие внимания (неявные геттеры) ---

	// 1. Состояние соединения (ConnState)
	// В debug.c есть CONN_SetState, предполагаем наличие CONN_GetState()
	// Если такой функции нет, закомментируйте следующую строку:
	// statusPacket.connState = CONN_GetState();


}

#endif
