using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    public float maxReactionWaitTime = 3f;
    public float minReactionWaitTime = 1.5f;
    public float reactionTimeAccelRate = 0.95f;
    private float curReactionCount;

    public Gesture currentGesture;
    private int currentGestureIndex;
    private Gesture.GestureName[] gestureNames;

    private PlayerHandController playerHand;
    private AIHandController aiHand;

    public ActionLines actionLines;

    private void Awake()
    {
        if (Instance != this)
        {
            Destroy(gameObject);
            return;
        }

        playerHand = FindObjectOfType<PlayerHandController>();
        aiHand = FindObjectOfType<AIHandController>();

        GestureManager.InitializeArray();

        actionLines.Hide();
    }

    private void Start()
    {
        gestureNames = GameMaster.Instance.GetGestureNames();
        currentGestureIndex = 0;

        StartBattle();
    }

    public void StartBattle()
    {
        curReactionCount = maxReactionWaitTime;

        AudioMaster.ResetCorrectHandPitch();

        StartCoroutine(StartRound());
    }

    public IEnumerator StartRound()
    {
        if (gestureNames != null)
            currentGesture = GestureManager.FindGestureByName(gestureNames[currentGestureIndex++]);
        else
            currentGesture = GestureManager.FindGestureByName(Gesture.GestureName.punch_front);

        yield return new WaitForSeconds(0.75f);

        playerHand.getPlayerInput = true;

        aiHand.SetFingersOut(currentGesture.fingersOut);
        aiHand.SetNormal(currentGesture.palmNormal, currentGesture.indexDirection);
        Debug.Log("Enemy gesture: " + currentGesture.gestureName + ", direction: " + currentGesture.indexDirection + ", palm: " + currentGesture.palmNormal);

        yield return new WaitForSeconds(0.25f);

		float timeCounter = 0;
        Gesture answerGesture = null;
        while (timeCounter < curReactionCount)
        {
            yield return new WaitForFixedUpdate();

            timeCounter += Time.deltaTime;
            answerGesture = ReadAnswerGesture();
            if (answerGesture != null)
            {
                playerHand.getPlayerInput = false;   
                break;
            }
        }

        if (answerGesture != null)
        {
            Debug.Log("Correct Gesture: " + answerGesture.gestureName + ", direction: " + answerGesture.GetPlayerIndexDirection() + ", palm: " + answerGesture.GetPlayerPalmDirection());
            playerHand.SetNormal(answerGesture.GetPlayerPalmDirection(), answerGesture.GetPlayerIndexDirection());

            yield return new WaitForSeconds(HandController.ROTATION_DURATION);

            AudioMaster.PlayCorrectHandClip(currentGestureIndex);
            actionLines.ShowLines(true);
            if (gestureNames != null && currentGestureIndex < gestureNames.Length)
            {
                StartCoroutine(StartRound());
            }
            else
            {
                Debug.Log("Victory!");
                StartCoroutine(WaitToClose(true));
            }
        }
        else
        {
            Debug.Log("Wrong Gesture");
            StartCoroutine(WaitToClose(false));
            AudioMaster.PlayWrongHandClip();
            actionLines.ShowLines(false);
        }

        curReactionCount = Mathf.Max(curReactionCount * reactionTimeAccelRate, minReactionWaitTime);
    }

    public Gesture ReadAnswerGesture()
    {
        Gesture answer = GestureManager.ReadAnswerGesture(currentGesture, playerHand.fingersOut);
        return answer;
    }

    private IEnumerator WaitToClose(bool closeBool)
    {
        yield return new WaitForSeconds(1f);

        GameMaster.Instance.CloseBattle(closeBool);
    }
}
