#pragma once

#include <iostream>
#include <string>
#include <string_view>

#include "stm32h7xx_ll_utils.h"

#include "StateVariables.hpp"
#include "BSP.hpp"
#include "RTClock.hpp"
#include "CPFUtilities.hpp"
#include "Logger.hpp"
#include "TimerMgr.hpp"

enum StateNames 
{
	initPlatform = 0,
	recovery,
	initProfile,
	submerge,
	descend,
	park,
	anchor,
	ascend,
	surfaceOps,
	numStates
};

struct StateEvent
{
	uint8_t id;
	std::string msg;
};
static StateEvent noEvent{0, "null event"};

static const std::string stmchEngLogID = "stmch";

class StateBase
{
public:
	StateBase(std::string state_label, uint32_t timeout_min);

	void doStdEntry();

	void doStdExit(bool timeout);

	static std::string_view getStateLabel()
	{
	}

	void enterState(void);
	virtual void doStateActions(const StateEvent event) = 0;
	virtual StateNames checkEvents(const StateEvent event) = 0;
	StateNames exitState(const StateEvent event);
	virtual void defineActionLabels() = 0;
	
	static void logEngFileHeader();
	void setStateTimeoutAlarm();

	const std::string stateLabel;

	void LogUnknownEvent(const StateEvent event)
	{
//		(void) msg;
//		Logger::logEngLine(ALWAYS, stmchEngMsgID, "Unknown event ID received: " + std::to_string(msg.get_message_id()));
	}

protected:
	virtual void enterThisState() = 0;
	virtual void exitThisState(StateEvent event) = 0;

	void smLogEngLine(std::string comment);
	virtual ~StateBase() = default;
	uint8_t doActionChange(std::string current, std::string next);	
	
	void setStateTimeout(StateNames stateName);
	void setInitialAction(uint8_t actionNum, std::string actionLabel);
	
	uint32_t stateTimeout_min;
	
	uint8_t currentAction;
	uint8_t nextAction;
	uint8_t previousAction;
	
private:
	void stdStateEntry();
	StateNames stdStateExit(const StateEvent event);
};
