using System;
using System.Diagnostics;
using Godot;

public partial class UIHandler : Control
{
	[Export] CodingWindow codingWindow;
	[Export] RobotList robotList;
	[Export] Camera3D mainCam;
	[Export] Map map;
	[Export] RichTextLabel FPS;
	[Export] RichTextLabel RAM;
	[Export] PanelContainer options;
	[Export] Control uiContent;
	[Export] PanelContainer menu;
	[Export] PanelContainer inventory;
	[Export] ResearchList researchList;
	[Export] TextureRect robotAlarm;
	[Export] RichTextLabel energyLabel;
	[Export] RichTextLabel waterLabel;
	[Export] RichTextLabel hungerLabel;
	[Export] RichTextLabel survivalStatus;
	[Export] RichTextLabel currentLayer;
	[Export] RichTextLabel deepestLayer;
	[Export] Button unlockLayer;
	[Export] PanelContainer gameOver;


	private bool receivedRobotJumpSignal = false;
	public override void _Ready()
	{
		robotList.OnRobotJumpTo += OnRobotJumpTo;
	}

	public override void _ExitTree()
	{
		robotList.OnRobotJumpTo -= OnRobotJumpTo;
	}

	public override void _Process(double delta)
	{
		DisplayStats();
		DisplayRobotAlarm();

		Control focused = GetViewport().GuiGetFocusOwner();

		if (focused is LineEdit || focused is TextEdit)
			return;

		if (Input.IsActionJustPressed("map")) HandleMapButton();
		if (Input.IsActionJustPressed("menu")) HandleMenuButton();
		if (Input.IsActionJustPressed("robot_list")) HandleRobotListButton();
		if (Input.IsActionJustPressed("inventory")) HandleInventoryButton();
		if (Input.IsActionJustPressed("research")) HandleResearchButton();
	}

	public void HandleMenuButton()
	{
		OpenUIElement(menu);
	}

	public void HandleMenu()
	{
		HandleMenuButton();
	}

	public void ShowOptions()
	{
		OpenUIElement(options);
	}

	public void HandleMapButton()
	{
		OpenUIElement(map);
		if (map.Visible) map.ShowMap();
	}

	public void HandleRobotListButton()
	{
		receivedRobotJumpSignal = false;
		OpenUIElement(robotList);
	}

	public void HandleInventoryButton()
	{
		OpenUIElement(inventory);
	}

	public void HandleResearchButton()
	{
		OpenUIElement(researchList);
		if (researchList.Visible) researchList.SetupGraph();
	}

	public void DisplayStats()
	{
		FPS.Text = Engine.GetFramesPerSecond().ToString() + " FPS";
		double memory = Process.GetCurrentProcess().WorkingSet64 / (1024 * 1024);
		string memoryDisplay = memory > 1024 ? Math.Round(memory / 1024, 2).ToString() + " GB" : memory.ToString() + " MB";
		RAM.Text = memoryDisplay;
		DisplaySurvivalStats();
		DisplayWorldStats();
	}

	public void ExitGame()
	{
		GetTree().ChangeSceneToFile("res://Scenes/MainMenu.tscn");
	}

	public void OpenUIElement(Control element)
	{
		if (element.Visible)
		{
			element.Hide();
		}
		else
		{
			element.Show();
		}
		HideUIElements(element);
	}

	private void HideUIElements(Control element)
	{
		foreach (PanelContainer child in uiContent.GetChildren())
		{
			if (child == element) continue;
			child.Visible = false;
		}
	}

	private void DisplayRobotAlarm()
	{
		string messages = "";
		if (GameData.survival.isDead)
		{
			messages += GameData.survival.currentStatus + "\r";
		}

		foreach (Robot robot in GameData.robots)
		{
			if (robot.currentMessage.Length > 0)
			{
				messages += $"{robot.Name}: {robot.currentMessage}\r";
			}
		}
		robotAlarm.Visible = messages.Length > 0;
		robotAlarm.TooltipText = messages;
	}

	private void OnRobotJumpTo(Robot robot)
	{
		if (receivedRobotJumpSignal) return;

		receivedRobotJumpSignal = true;
		mainCam.Position = new Vector3(robot.Position.X, mainCam.Position.Y, robot.Position.Z + 3f);
		codingWindow.SetRobot(robot);
		OpenUIElement(codingWindow);
	}

	private void DisplaySurvivalStats()
	{
		energyLabel.Text = $"Energy: {GameData.survival.energy:0}/{GameData.survival.maxEnergy:0}";
		waterLabel.Text = $"Water: {GameData.survival.thirst:0}/{GameData.survival.maxThirst:0}";
		hungerLabel.Text = $"Food: {GameData.survival.hunger:0}/{GameData.survival.maxHunger:0}";
		survivalStatus.Text = GameData.survival.currentStatus;
		if (GameData.survival.isDead)
		{
			ShowGameOver();
		}
	}

	private void DisplayWorldStats()
	{
		currentLayer.Text = $"Current layer: {GameData.currentLayer}/{GameData.ruinSize}";
		deepestLayer.Text = $"Deepest layer: {GameData.lowestLayer}";
		if(GameData.lowestLayer == GameData.ruinSize){
			unlockLayer.Visible = false;
			return;
		}
		unlockLayer.TooltipText = "Needed items: \r" + GameData.map[GameData.lowestLayer].DisplayGateIngredients();
		unlockLayer.Disabled = !GameData.inventory.CanCraft(GameData.map[GameData.lowestLayer].gateIngredients, 1);
	}

	public void UnlockLayer()
	{
		if (GameData.inventory.CanCraft(GameData.map[GameData.lowestLayer].gateIngredients, 1))
		{
			foreach (Ingredient ingredient in GameData.map[GameData.lowestLayer].gateIngredients)
			{
				GameData.inventory.RemoveItem(ingredient.Item, ingredient.Amount);
			}
			GameData.lowestLayer++;
			if (GameData.lowestLayer == GameData.ruinSize)
			{
				gameOver.Show();
			}
		}
	}

	public void ShowGameOver()
	{
		if(gameOver.Visible) return;
		gameOver.GetNode<RichTextLabel>("./VBoxContainer/Content").Text = $"[font_size=32]You died! \r Reason: {GameData.survival.deathReason} \r Better luck next time \r";
		gameOver.Show();
	}

	public void HideGameOver()
	{
		gameOver.Hide();
	}
}
