#include "MenuManager.h"
#include <iostream>

#ifdef EMSCRIPTEN
#include <emscripten.h>
#include <cstdlib>
#endif

namespace ZL {

	extern bool inverseVertical;

	MenuManager::MenuManager(Renderer& iRenderer) :
		renderer(iRenderer)
	{
	}

	/*
	void MenuManager::setupMenu()
	{
		mainMenuRoot        = loadUiFromFile("resources/config/main_menu.json",           renderer, CONST_ZIP_FILE);
		aboutMenuRoot       = loadUiFromFile("resources/config/about.json", renderer, CONST_ZIP_FILE);
		shipSelectionRoot   = loadUiFromFile("resources/config/ship_selection_menu.json", renderer, CONST_ZIP_FILE);
		connectingRoot      = loadUiFromFile("resources/config/connecting.json",          renderer, CONST_ZIP_FILE);
		connectionFailedRoot= loadUiFromFile("resources/config/connection_failed.json",   renderer, CONST_ZIP_FILE);
		gameplayRoot        = loadUiFromFile("resources/config/ui.json",                  renderer, CONST_ZIP_FILE);
		gameOverRoot        = loadUiFromFile("resources/config/game_over.json",           renderer, CONST_ZIP_FILE);
		helpScreenRoot      = loadUiFromFile("resources/config/ui_with_help.json",        renderer, CONST_ZIP_FILE);
		connectionLostRoot  = loadUiFromFile("resources/config/connection_lost.json",     renderer, CONST_ZIP_FILE);

		enterMainMenu();
	}

	bool MenuManager::shouldRenderSpace() const
	{
		return state == GameState::Gameplay
			|| state == GameState::GameOver
			|| state == GameState::HelpScreen
			|| state == GameState::ConnectionLost;
	}

	// ── State: MainMenu ──────────────────────────────────────────────────────

	void MenuManager::enterMainMenu()
	{
		state = GameState::MainMenu;
		uiManager.replaceRoot(mainMenuRoot);

		if (onMainMenuEntered) onMainMenuEntered();

		uiManager.setButtonCallback("singleButton", [this](const std::string&) {
			enterShipSelectionSingle();
			});

		uiManager.setButtonCallback("multiplayerButton", [this](const std::string&) {
			enterShipSelectionMulti();
			});

		uiManager.setButtonCallback("aboutButton", [this](const std::string&) {
			enterAboutMenu();
			});
	}


	void MenuManager::enterAboutMenu()
	{
		state = GameState::AboutMenu;
		uiManager.replaceRoot(aboutMenuRoot);
		uiManager.setButtonCallback("aboutBackButton", [this](const std::string&) {
			enterMainMenu();
		});
	}

	// ── State: ShipSelectionSingle ───────────────────────────────────────────

	void MenuManager::enterShipSelectionSingle()
	{
		state = GameState::ShipSelectionSingle;
		uiManager.replaceRoot(shipSelectionRoot);

		std::string initialNick;
#ifdef EMSCRIPTEN
		char* savedNickC = emscripten_run_script_string("localStorage.getItem('spacegame_nick') || ''");
		if (savedNickC) {
			initialNick = savedNickC;
			free(savedNickC);
		}
#endif

		auto tf = uiManager.findTextField("nicknameInput");
		if (tf) {
			if (!initialNick.empty()) tf->text = initialNick;

#ifdef EMSCRIPTEN
			uiManager.setTextFieldCallback("nicknameInput", [](const std::string&, const std::string& value) {
				EM_ASM_({
					try { localStorage.setItem('spacegame_nick', UTF8ToString($0)); } catch(e) {}
				}, value.c_str());
			});
#endif
		}

		uiManager.setButtonCallback("spaceshipButton", [this, initialNick](const std::string&) {
			std::string nick = uiManager.getTextFieldValue("nicknameInput");
			if (nick.empty()) nick = initialNick;
			if (nick.empty()) nick = "Player";
			enterGameplay();
			if (onSingleplayerPressed) onSingleplayerPressed(nick, 0);
			});

		uiManager.setButtonCallback("cargoshipButton", [this, initialNick](const std::string&) {
			std::string nick = uiManager.getTextFieldValue("nicknameInput");
			if (nick.empty()) nick = initialNick;
			if (nick.empty()) nick = "Player";
			enterGameplay();
			if (onSingleplayerPressed) onSingleplayerPressed(nick, 1);
			});

		uiManager.setButtonCallback("backButton", [this](const std::string&) {
			enterMainMenu();
			});
	}

	// ── State: ShipSelectionMulti ─────────────────────────────────────────────

	void MenuManager::enterShipSelectionMulti()
	{
		state = GameState::ShipSelectionMulti;
		uiManager.replaceRoot(shipSelectionRoot);

		std::string initialNick;
#ifdef EMSCRIPTEN
		char* savedNickC = emscripten_run_script_string("localStorage.getItem('spacegame_nick') || ''");
		if (savedNickC) {
			initialNick = savedNickC;
			free(savedNickC);
		}
#endif

		auto tf = uiManager.findTextField("nicknameInput");
		if (tf) {
			if (!initialNick.empty()) tf->text = initialNick;

#ifdef EMSCRIPTEN
			uiManager.setTextFieldCallback("nicknameInput", [](const std::string&, const std::string& value) {
				EM_ASM_({
					try { localStorage.setItem('spacegame_nick', UTF8ToString($0)); } catch(e) {}
				}, value.c_str());
			});
#endif
		}

		uiManager.setButtonCallback("spaceshipButton", [this, initialNick](const std::string&) {
			std::string nick = uiManager.getTextFieldValue("nicknameInput");
			if (nick.empty()) nick = initialNick;
			if (nick.empty()) nick = "Player";
			pendingMultiNick = nick;
			pendingMultiShipType = 0;
			enterConnecting();
			if (onMultiplayerPressed) onMultiplayerPressed(nick, 0);
			});

		uiManager.setButtonCallback("cargoshipButton", [this, initialNick](const std::string&) {
			std::string nick = uiManager.getTextFieldValue("nicknameInput");
			if (nick.empty()) nick = initialNick;
			if (nick.empty()) nick = "Player";
			pendingMultiNick = nick;
			pendingMultiShipType = 1;
			enterConnecting();
			if (onMultiplayerPressed) onMultiplayerPressed(nick, 1);
			});

		uiManager.setButtonCallback("backButton", [this](const std::string&) {
			enterMainMenu();
			});
	}

	// ── State: Connecting ────────────────────────────────────────────────────

	void MenuManager::enterConnecting()
	{
		state = GameState::Connecting;
		uiManager.replaceRoot(connectingRoot);
		// No interactive elements — just a static "Connecting..." image
	}

	// ── State: ConnectionFailed ───────────────────────────────────────────────

	void MenuManager::enterConnectionFailed()
	{
		state = GameState::ConnectionFailed;
		uiManager.replaceRoot(connectionFailedRoot);

		uiManager.setButtonCallback("connectionFailedReconnectButton", [this](const std::string&) {
			enterConnecting();
			if (onMultiplayerPressed) onMultiplayerPressed(pendingMultiNick, pendingMultiShipType);
			});

		uiManager.setButtonCallback("connectionFailedGoBack", [this](const std::string&) {
			enterMainMenu();
			});
	}

	// ── State: Gameplay ──────────────────────────────────────────────────────

	void MenuManager::enterGameplay()
	{
		state = GameState::Gameplay;
		uiManager.replaceRoot(gameplayRoot);

		if (Environment::shipState.shipType == 1)
		{
			uiManager.findButton("shootButton")->state = ButtonState::Disabled;
			uiManager.findButton("shootButton2")->state = ButtonState::Disabled;
		}
		else
		{
			if (Environment::shipState.velocity < 0.1)
			{
				uiManager.findButton("minusButton")->state = ButtonState::Disabled;
				uiManager.findButton("plusButton")->state = ButtonState::Normal;
				uiManager.findButton("shootButton")->state = ButtonState::Normal;
				uiManager.findButton("shootButton2")->state = ButtonState::Normal;
			}
			else if (Environment::shipState.velocity >= 0.1 && Environment::shipState.velocity <= 200)
			{
				uiManager.findButton("minusButton")->state = ButtonState::Normal;
				uiManager.findButton("plusButton")->state = ButtonState::Normal;
				uiManager.findButton("shootButton")->state = ButtonState::Normal;
				uiManager.findButton("shootButton2")->state = ButtonState::Normal;
			}
			else if (Environment::shipState.velocity > 200 && Environment::shipState.velocity < 400 - 0.1)
			{
				uiManager.findButton("minusButton")->state = ButtonState::Normal;
				uiManager.findButton("plusButton")->state = ButtonState::Normal;
				uiManager.findButton("shootButton")->state = ButtonState::Disabled;
				uiManager.findButton("shootButton2")->state = ButtonState::Disabled;
			}
			else if (Environment::shipState.velocity >= 400 - 0.1)
			{
				uiManager.findButton("minusButton")->state = ButtonState::Normal;
				uiManager.findButton("plusButton")->state = ButtonState::Disabled;
				uiManager.findButton("shootButton")->state = ButtonState::Disabled;
				uiManager.findButton("shootButton2")->state = ButtonState::Disabled;
			}
		}

		if (forceSetupSpaceUICallback)
		{
			forceSetupSpaceUICallback();
		}

		if (auto btn = uiManager.findButton("takeButton")) btn->state = ButtonState::Disabled;
		if (auto btn = uiManager.findButton("showPlayersButton"))
		{
			btn->state = ButtonState::Disabled;
		}


	

		uiManager.setButtonPressCallback("shootButton", [this](const std::string&) {
			if (onFirePressed) onFirePressed();
			});
		uiManager.setButtonPressCallback("shootButton2", [this](const std::string&) {
			if (onFirePressed) onFirePressed();
			});
		uiManager.setButtonPressCallback("plusButton", [this](const std::string&) {
			int newVel = Environment::shipState.selectedVelocity + 1;
			if (newVel > 4) newVel = 4;
			uiManager.findButton("minusButton")->state = ButtonState::Normal;
			if (newVel == 4)
			{
				uiManager.findButton("plusButton")->state = ButtonState::Disabled;
			}
			else
			{
				uiManager.findButton("plusButton")->state = ButtonState::Normal;
			}
			if (onVelocityChanged) onVelocityChanged(newVel);
			});
		uiManager.setButtonPressCallback("minusButton", [this](const std::string&) {
			int newVel = Environment::shipState.selectedVelocity - 1;
			if (newVel < 0) newVel = 0;
			uiManager.findButton("plusButton")->state = ButtonState::Normal;
			if (newVel == 0)
			{
				uiManager.findButton("minusButton")->state = ButtonState::Disabled;
			}
			else
			{
				uiManager.findButton("minusButton")->state = ButtonState::Normal;
			}
			if (onVelocityChanged) onVelocityChanged(newVel);
			});

		uiManager.setButtonPressCallback("takeButton", [this](const std::string&) {
			if (onTakeButtonPressed) onTakeButtonPressed();
			});

		uiManager.setButtonCallback("showPlayersButton", [this](const std::string&) {
			if (onShowPlayersPressed) onShowPlayersPressed();
			});

		uiManager.setButtonPressCallback("inverseMouseButton", [this](const std::string&) {
			inverseVertical = !inverseVertical;
			std::cout << "Inverse mouse: " << (inverseVertical ? "ON" : "OFF") << std::endl;
			});

		uiManager.setButtonCallback("infoButton", [this](const std::string&) {
			//if (onShowPlayersPressed) onShowPlayersPressed();
			enterHelp();
			});


	}

	// ── State: GameOver ──────────────────────────────────────────────────────

	void MenuManager::enterGameOver(int score)
	{
		state = GameState::GameOver;
		uiManager.replaceRoot(gameOverRoot);

		uiManager.setText("scoreText", "Score: " + std::to_string(score));

		uiManager.setButtonCallback("restartButton", [this](const std::string&) {
			if (onRestartPressed) onRestartPressed();
			enterGameplay();
			});
		uiManager.setButtonCallback("gameOverExitButton", [this](const std::string&) {
			enterMainMenu();
			});
	}

	void MenuManager::enterHelp()
	{
		state = GameState::HelpScreen;
		uiManager.replaceRoot(helpScreenRoot);

		uiManager.setButtonCallback("infoButtonUnderlying_help", [this](const std::string&) {
			enterGameplay();
			});
	}

	// ── State: ConnectionLost ─────────────────────────────────────────────────

	void MenuManager::enterConnectionLost()
	{
		state = GameState::ConnectionLost;
		uiManager.replaceRoot(connectionLostRoot);

		uiManager.setButtonCallback("reconnectButton", [this](const std::string&) {
			enterConnecting();
			if (onMultiplayerPressed) onMultiplayerPressed(pendingMultiNick, pendingMultiShipType);
			});
		uiManager.setButtonCallback("exitServerButton", [this](const std::string&) {
			enterMainMenu();
			});
	}

	// ── Public event API ──────────────────────────────────────────────────────

	void MenuManager::notifyConnected()
	{
		if (state == GameState::Connecting) {
			enterGameplay();
		}
	}

	void MenuManager::notifyConnectionFailed()
	{
		if (state == GameState::Connecting) {
			enterConnectionFailed();
		}
	}

	void MenuManager::showGameOver(int score)
	{
		if (state == GameState::Gameplay) {
			enterGameOver(score);
		}
	}

	void MenuManager::showConnectionLost()
	{
		if (state == GameState::Gameplay) {
			enterConnectionLost();
		}
	}*/

} // namespace ZL