using Godot;

// Демо-карта «убежища» в разрезе (à la Fallout Shelter): сетка комнат из игровых текстур.
//   ЛКМ-перетаскивание или WASD/стрелки — панорама
//   колесо мыши — зум,  R — сброс вида
public partial class RoomMap : Node2D
{
	private const float Cell = 256f;
	private const int Cols = 6;
	private const int Rows = 5;

	private Node2D _world;
	private Label _label;
	private bool _dragging;
	private float _viewZoom = 1f;
	private Vector2 _homePos;

	public override void _Ready()
	{
		var bg = new ColorRect
		{
			Color = new Color(0.06f, 0.05f, 0.04f), // земля вокруг убежища
			AnchorRight = 1, AnchorBottom = 1,
			MouseFilter = Control.MouseFilterEnum.Ignore
		};
		AddChild(bg);

		_world = new Node2D();
		AddChild(_world);

		BuildVault();

		_label = new Label { Position = new Vector2(16, 12) };
		_label.AddThemeFontSizeOverride("font_size", 18);
		_label.AddThemeConstantOverride("outline_size", 4);
		_label.AddThemeColorOverride("font_outline_color", Colors.Black);
		AddChild(_label);

		ResetView();
	}

	private void BuildVault()
	{
		// «поверхность» над убежищем
		AddTex("res://assets/backgrounds/background_sky.png",
			new Rect2(-Cell, -Cell * 1.2f, Cols * Cell + Cell * 2, Cell * 1.2f), _world, new Color(1, 1, 1, 0.9f));

		// пол каждой ячейки — пустая комната (шахматкой две вариации)
		for (int r = 0; r < Rows; r++)
			for (int c = 0; c < Cols; c++)
			{
				string tex = (r + c) % 2 == 0
					? "res://assets/room_sliced/Room_normal.png"
					: "res://assets/room_sliced/Room_normal2.png";
				AddCell(tex, c, r, 1, 1);
			}

		// несколько «обставленных» комнат-акцентов поверх пустых
		AddCell("res://assets/room_sliced/PlayerRoom.png", 1, 0, 3, 1);        // широкая на 3 клетки
		AddCell("res://assets/room_sliced/BreedingRoom.png", 0, 2, 1, 1);
		AddCell("res://assets/room_sliced/LactationRoom.png", 4, 3, 1, 1);
		AddCell("res://assets/room_sliced/Light.png", 2, 2, 1, 1);

		// рамки поверх всех ячеек — читаемость сетки
		for (int r = 0; r < Rows; r++)
			for (int c = 0; c < Cols; c++)
				AddCell("res://assets/room_sliced/Frame.png", c, r, 1, 1, new Color(1, 1, 1, 0.5f));
	}

	private void AddCell(string path, int col, int row, int cw, int ch, Color? modulate = null)
	{
		AddTex(path, new Rect2(col * Cell, row * Cell, cw * Cell, ch * Cell), _world, modulate ?? Colors.White);
	}

	private static void AddTex(string path, Rect2 dest, Node2D parent, Color modulate)
	{
		var tex = ResourceLoader.Exists(path) ? ResourceLoader.Load<Texture2D>(path) : null;
		if (tex == null)
			return;
		var s = new Sprite2D
		{
			Texture = tex,
			Centered = false,
			Position = dest.Position,
			Scale = new Vector2(dest.Size.X / tex.GetWidth(), dest.Size.Y / tex.GetHeight()),
			Modulate = modulate
		};
		parent.AddChild(s);
	}

	private void ResetView()
	{
		Vector2 vp = GetViewportRect().Size;
		Vector2 gridSize = new Vector2(Cols * Cell, Rows * Cell);
		float fit = Mathf.Min(vp.X * 0.9f / gridSize.X, vp.Y * 0.8f / gridSize.Y);
		_viewZoom = fit;
		_world.Scale = new Vector2(fit, fit);
		_homePos = (vp - gridSize * fit) * 0.5f;
		_world.Position = _homePos;
		UpdateLabel();
	}

	private void ZoomAt(Vector2 screenPoint, float factor)
	{
		float newZoom = Mathf.Clamp(_viewZoom * factor, 0.1f, 3f);
		factor = newZoom / _viewZoom;
		_viewZoom = newZoom;
		// удерживаем точку под курсором на месте
		_world.Position = screenPoint - (screenPoint - _world.Position) * factor;
		_world.Scale = new Vector2(_viewZoom, _viewZoom);
		UpdateLabel();
	}

	private void UpdateLabel()
	{
		_label.Text =
			$"Карта убежища — {Cols}×{Rows} комнат из игровых текстур\n" +
			$"ЛКМ/WASD — панорама   ·   колесо — зум (x{_viewZoom:0.00})   ·   R — сброс   ·   Esc — меню";
	}

	public override void _Process(double delta)
	{
		if (!Visible)
			return;
		Vector2 dir = Vector2.Zero;
		if (Input.IsKeyPressed(Key.A) || Input.IsKeyPressed(Key.Left)) dir.X += 1;
		if (Input.IsKeyPressed(Key.D) || Input.IsKeyPressed(Key.Right)) dir.X -= 1;
		if (Input.IsKeyPressed(Key.W) || Input.IsKeyPressed(Key.Up)) dir.Y += 1;
		if (Input.IsKeyPressed(Key.S) || Input.IsKeyPressed(Key.Down)) dir.Y -= 1;
		if (dir != Vector2.Zero)
			_world.Position += dir * (float)delta * 600f;
	}

	public override void _UnhandledInput(InputEvent @event)
	{
		if (@event is InputEventKey esc && esc.Pressed && esc.Keycode == Key.Escape)
		{
			GetTree().ChangeSceneToFile("res://scenes/MainMenu.tscn");
			return;
		}
		if (@event is InputEventMouseButton mb)
		{
			if (mb.ButtonIndex == MouseButton.Left)
				_dragging = mb.Pressed;
			else if (mb.Pressed && mb.ButtonIndex == MouseButton.WheelUp)
				ZoomAt(mb.Position, 1.1f);
			else if (mb.Pressed && mb.ButtonIndex == MouseButton.WheelDown)
				ZoomAt(mb.Position, 1f / 1.1f);
		}
		else if (@event is InputEventMouseMotion mm && _dragging)
		{
			_world.Position += mm.Relative;
		}
		else if (@event is InputEventKey k && k.Pressed && !k.Echo && k.Keycode == Key.R)
		{
			ResetView();
		}
	}
}
