using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class NeighborhoodMaster : MonoBehaviour
{   
    private static NeighborhoodMaster _instance;
    public static NeighborhoodMaster Instance
    {
        get
        {
            if (_instance == null)
                _instance = FindObjectOfType<NeighborhoodMaster>();
            return _instance;
        }
    }

	public Character[] characterPrefabs;
	private Character[] characters;

    private Character currentCharacter;
    private bool hasCharacter;

    public SpriteRenderer feedbackFace;
    public Sprite faceGood, faceBad;

    private void Awake()
    {
        if (Instance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            DontDestroyOnLoad(this.gameObject);
        }

        characters = new Character[characterPrefabs.Length];
        for (int i = 0; i < characterPrefabs.Length; i++)
        {
            characters[i] = Instantiate(characterPrefabs[i]);
        }
    }

    private void Start()
    {
        for (int i = 0; i < characters.Length; i++)
        {
            characters[i].SetIndex(i);
        }
        StartNeighbor();
        feedbackFace.gameObject.SetActive(false);
        AudioMaster.StartMainSong();
    }

	private void Update()
	{
        if (Input.GetButtonDown("Thumb") && GameMaster.Instance.currentState == GameMaster.GameState.neighborhood && currentCharacter.isAvailable)
        {
            CallNeighbor();
        }
    }

    public void StartNeighbor()
    {
		StartCoroutine (StartNeighborCoroutine ());
    }

	private IEnumerator StartNeighborCoroutine()
	{
		int characterIndex;
		
		do
		{
			characterIndex = Random.Range(0, characters.Length);
			yield return 0;
		}
		while (characters[characterIndex].isActive);
		
		currentCharacter = characters[characterIndex];
		
		currentCharacter.OnCharacterIgnored += OnNeighborIgnored;
		currentCharacter.StartMovement();
	}

    public void CallNeighbor()
    {
        currentCharacter.StopMovement();
        currentCharacter.OnCharacterIgnored -= OnNeighborIgnored;
        AudioMaster.PlayWaveClip();

        StartCoroutine(WaitForBattle());
    }

    public void OnNeighborIgnored()
    {
        Debug.Log("Ignored");
        currentCharacter.OnCharacterIgnored -= OnNeighborIgnored;
        StartNeighbor();
    }

    private IEnumerator WaitForBattle()
    {
        GameMaster.Instance.currentState = GameMaster.GameState.battle;
        yield return new WaitForSeconds(1f);
        EnterBattle();
    }

    public void EnterBattle()
    {
        Debug.Log("Intimacy: " + currentCharacter.GetGestures().Length.ToString());
        GameMaster.Instance.OpenBattle(currentCharacter.GetGestures());
    }

    public void BackFromBattle(bool victory)
    {
        if (victory)
            currentCharacter.IncreaseIntimacy();
        else
            currentCharacter.DecreaseIntimacy();
        ShowFeedbackFace(victory);
        StartCoroutine(WaitForNeighbor());
    }

    private IEnumerator WaitForNeighbor()
    {
        yield return new WaitForSeconds(0.5f);
        currentCharacter.ContinueMovement();
        yield return new WaitForSeconds(2f);
        StartNeighbor();
    }

    public void ShowFeedbackFace(bool isHappy)
    {
        feedbackFace.gameObject.SetActive(true);
        feedbackFace.transform.position = new Vector3(currentCharacter.transform.position.x, 2.25f, 0);
        feedbackFace.sprite = (isHappy) ? faceGood : faceBad;

        Sequence tween = DOTween.Sequence();
        tween.Insert(0, feedbackFace.DOFade(1, 0));
        tween.Insert(0, feedbackFace.transform.DOScale(Vector3.zero, 0.5f).SetEase(Ease.OutBack).From());
        tween.Insert(0, feedbackFace.transform.DOMoveY(feedbackFace.transform.position.y - 1.75f, 0.5f).SetEase(Ease.OutBack).From());
        tween.Append(feedbackFace.transform.DOMoveY(feedbackFace.transform.position.y + 2.25f, 2f));
        tween.Join(feedbackFace.DOFade(0, 0.75f));
        tween.AppendCallback(() => feedbackFace.gameObject.SetActive(false));
    }
}