using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class GodManager : MonoBehaviour
{
	public static GodManager instance { get; private set; }
	public GameObject[] godRefs;
	public Sprite[] godSprites;
	public godState currentState;
	public float delayTimeBeforeProcessSacrifice;

	float lastStateChangeTime;

	public enum godState
	{
		leaveScreen,
		reset,
		enterScreen,
		waitingForInput,
		delayBeforeProcessingSacrifice,
		processingSacrifice,
		finishedSacrifice
	};

	public ResourceManager.BuildingResources offeredSacrifice;

	public int currentGodProcessing;

	void Awake()
	{
		instance = this;
		currentGodProcessing = 0;
	}

	void Reset()
	{
		delayTimeBeforeProcessSacrifice = 3.0f;
	}

	void Start()
	{
		//Move Gods offscreen at start
		for (int i=0; i<godRefs.Length; i++)
		{
			godRefs[i].GetComponent<RectTransform>().anchoredPosition = godRefs[i].GetComponent<God>().offscreenPosition;
		}
	}

	public void setStartingGods()
	{
		for(int i=0; i<godRefs.Length; i++)
		{
			God g = godRefs[i].GetComponent<God>();
			int diff = g.angerMax - g.currentAnger;
			for (int j=0; j<diff; j++) { g.increaseAnger(); }
		}
		checkForNewGod();
	}

	void Update()
	{
		if (SpeechBubbleController.instance.transform.parent.GetComponent<CanvasGroup>().interactable ||
			TitleScreen.instance.GetComponent<CanvasGroup>().interactable) { return; }

		if (currentState == godState.enterScreen && 
			((int)GameManager.instance.currentGameState <= (int)GameManager.GameState.SetNewGods ||
				GameManager.instance.currentGameState == GameManager.GameState.WaitingForGod))
		{
			int numThatAreStillMoving = 0;
			for (int i=0; i<godRefs.Length; i++)
			{
				RectTransform rt = godRefs[i].GetComponent<RectTransform>();
				God g = godRefs[i].GetComponent<God>();
				if (g.currentAnger < g.angerMax &&
					(rt.anchoredPosition - g.onscreenPosition).magnitude > Time.deltaTime * g.godMoveAnimateSpeed)
				{
					//TODO: Vector3 adjustedOnscreenPosition = g.onscreenPosition
					rt.anchoredPosition = Vector2.Lerp(rt.anchoredPosition, g.onscreenPosition, Time.deltaTime * g.godMoveAnimateSpeed);
					numThatAreStillMoving++;
				}
			}

			if (numThatAreStillMoving <= 0)
			{
				GameManager.instance.changeState(GameManager.GameState.ChooseAProperty);
			}
		}

		else if (currentState == godState.leaveScreen &&
			((int)GameManager.instance.currentGameState <= (int)GameManager.GameState.SetNewGods ||
				GameManager.instance.currentGameState == GameManager.GameState.WaitingForGod))
		{
			int numThatAreStillMoving = 0;
			for (int i=0; i<godRefs.Length; i++)
			{
				RectTransform rt = godRefs[i].GetComponent<RectTransform>();
				God g = godRefs[i].GetComponent<God>();

				bool shouldLeaveScreen = (g.currentAppeasement >= g.appeasementMax || g.currentAnger >= g.angerMax) &&
					(rt.anchoredPosition - g.offscreenPosition).magnitude > Time.deltaTime * g.godMoveAnimateSpeed;

				if (shouldLeaveScreen)
				{
					rt.anchoredPosition = Vector2.Lerp(rt.anchoredPosition, g.offscreenPosition, Time.deltaTime * g.godMoveAnimateSpeed);
					numThatAreStillMoving++;
				}
			}

			if (numThatAreStillMoving <= 0)
			{
				GameManager.instance.changeState(GameManager.GameState.BuildingRefresh);
			}
		}

		else if (currentState == godState.delayBeforeProcessingSacrifice)
		{
			if (Time.time - lastStateChangeTime > delayTimeBeforeProcessSacrifice)
			{
				updateGodState(godState.processingSacrifice);
			}
		}

		else if (currentState == godState.processingSacrifice)
		{
			God ThisGodComponent = godRefs[currentGodProcessing].GetComponent<God>();

			if (ThisGodComponent.IsProcessingSacrifice == false)
			{
				++currentGodProcessing;

				// All three gods have finished processing sacrifices, so go to next state
				if (currentGodProcessing == godRefs.Length)
				{
					updateGodState(godState.leaveScreen);
					return;
				}

				godRefs[currentGodProcessing].GetComponent<God>().OfferSacrifice(offeredSacrifice);
			}
		}
	}

	public void checkForNewGod()
	{
		for (int i=0; i<godRefs.Length; i++)
		{
			//Reset God colours to default
			godRefs[i].GetComponent<God>().targetColour = Color.white;

			God g = godRefs[i].GetComponent<God>();
			if (g.currentAppeasement < g.appeasementMax && g.currentAnger < g.angerMax) { continue; }

			//Only pick personalities that have available resources in buildings
			int personalityIndex = -1;
			BuildingManager.instance.refreshBuildingReferences();
			bool isPersonalityValid = false;
			while (!isPersonalityValid)
			{
				personalityIndex = Random.Range(0, (int)ResourceManager.GodPersonalities.numOfGodPersonalities-1);

				//Don't allow duplicate Gods
				if (i > 0)
				{
					bool shouldBailEarly = false;
					for (int j=i-1; j>=0; j--)
					{
						if (godRefs[j].GetComponent<God>().personality == (ResourceManager.GodPersonalities)personalityIndex)
						{
							shouldBailEarly = true;
							break;
						}
					}
					if (shouldBailEarly) { continue; }
				}

				//Check for resources available in the buildings
				for(int j=0; j<BuildingManager.instance.buildings.Length; j++)
				{
					if (ResourceManager.isGodAppeased((ResourceManager.GodPersonalities)personalityIndex, 
						BuildingManager.instance.buildings[j].GetComponent<Building>().currentResource))
					{
						godRefs[i].GetComponent<God>().setPersonality((ResourceManager.GodPersonalities)personalityIndex);
						isPersonalityValid = true;
						break;
					}
				}
			}

            God NewGod = godRefs[i].GetComponent<God>();
			NewGod.setNewAngerAndAppeasement(Random.Range(3,6), Random.Range(3,5));
			NewGod.GetComponent<Image>().sprite = godSprites[Random.Range(0, godSprites.Length)];
		}
	}

	public void updateGodState(godState newGodState)
	{
		Debug.Log("Updating God state: "+newGodState.ToString());

		currentState = newGodState;
		lastStateChangeTime = Time.time;

		switch (newGodState)
		{
		case godState.reset:
			// Reset anim state
			for(int i=0;i < godRefs.Length ;i++)
			{
				godRefs[i].GetComponent<Animator>().SetTrigger("reset");
			}
			// move the position immediately
			break;

		case godState.delayBeforeProcessingSacrifice:
			//Update colours based on correct answer
			for (int i=0; i<godRefs.Length; i++)
			{
				God g = godRefs[i].GetComponent<God>();
				bool isAppeased = ResourceManager.isGodAppeased(g.personality, offeredSacrifice);
				g.targetColour = isAppeased ? Color.green : Color.red;
			}
			break;

		case godState.processingSacrifice:
			currentGodProcessing = 0;
			godRefs[currentGodProcessing].GetComponent<God>().OfferSacrifice(offeredSacrifice);
			break;

		default:
			break;
		}
	}
}
