﻿using System.Linq;
using UnityEngine;
using Gamelogic.AbstractStrategy.Grids;
using Gamelogic.Diagnostics;
using Gamelogic.Grids;
using UnityEngine.UI;

namespace Gamelogic.AbstractStrategy.Examples
{
	public class ShowGameOverMessageGame : GLMonoBehaviour
	{
		public Text text;
		public bool showWinnerID = true;
		public string customText;

		private GridGameManager manager;
		private Player<RectPoint, GridGamePieceSettings> redPlayer, bluePlayer;
		private IPieceProperties selectedPiece;

		public void Start()
		{
			InitializeGameManager();
			InitializePlayers();
			ResetGame();

			if (showWinnerID)
			{
				manager.OnGameOver += OnGameOver;
			}
			else
			{
				if (customText == string.Empty)
				{
					customText = "Game Over!\nPress Space to restart";
				}

				manager.OnGameOver += () => ShowMessage(customText);
				
			}
		}

		public void Update()
		{
			if (Input.GetKeyDown(KeyCode.Space))
			{
				ResetGame();
			}
		}

		public void OnClick(RectPoint point)
		{
			var currentPlayer = manager.CurrentPlayer;

			if (currentPlayer is GridHumanPlayer &&
				manager.MoveManager.Done)
			{
				// If a block is occupied, try to select
				var state = manager.State;
				var piece = state.TestPosition(point);

				if (piece != null)
				{
					if (piece.playerID == currentPlayer.PlayerID)
					{
						SelectPiece(piece);
					}
				}
				else if (selectedPiece != null)
				{
					// Try to commit move
					var selectedPos = state.FindPiece(selectedPiece);
					var move = state.CreateMovePieceMove(selectedPiece, selectedPos, point);

					if (manager.CommitMove(move))
					{
						DeselectPiece();
					}
				}
			}
		}

		private void ResetGame()
		{
			text.gameObject.SetActive(false);
			manager.StartGame();
		}

		private void InitializeGameManager()
		{
			manager = GetComponent<GridGameManager>();

			if (manager == null)
			{
				GLDebug.LogError("You must have a GridGameManager attached to the same game object as this component");
			}
		}

		private void InitializePlayers()
		{
			redPlayer = new GridHumanPlayer("red");
			bluePlayer = new GridHumanPlayer("blue");

			manager.RegisterPlayer(redPlayer);
			manager.RegisterPlayer(bluePlayer);
		}

		private void DeselectPiece()
		{
			if (selectedPiece != null)
			{
				UpdateVisualSelectionState(false);
			}

			selectedPiece = null;
		}

		private void SelectPiece(IPieceProperties piece)
		{
			if (selectedPiece != null)
			{
				DeselectPiece();
			}

			selectedPiece = piece;

			UpdateVisualSelectionState(true);
		}

		private void UpdateVisualSelectionState(bool selectionOn)
		{
			var visualPiece = manager.GetExistingVisualPiece(selectedPiece);
			var sprite = visualPiece.GetComponentInChildren<SpriteRenderer>();

			if (sprite != null)
			{
				var colour = sprite.color;
				colour.a = selectionOn ? 0.8f : 1.0f;
				sprite.color = colour;
			}
		}

		private void OnGameOver()
		{
			var winner = manager.Winners.First();

			ShowMessage(
				string.Format("The winner is {0}. \nPress <SPACE> to play again.", winner.PlayerID));
		}

		private void ShowMessage(string message)
		{
			text.gameObject.SetActive(true);
			text.text = message;
		}
	}
}