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

public class Water : ActiveBlock
{
    [Header("Water Settings")]
    [SerializeField]
    [Tooltip("GameObject which appears when character respawns")]
    private GameObject lillyPad;

    [SerializeField]
    [Tooltip("Distance character will be submerged into the water")]
    private float FallDistance = 0.5f;

    [SerializeField]
    private bool lillyPadStartUp = false;

    private bool isLillyPadUp = false;

    private Character trappedCharacter;

    public override int GetInitative()
    {
        return 0;
    }

    private void Start()
    {
        if (lillyPadStartUp)
        {
            StartCoroutine(LerpToPosition(lillyPad.transform, VisualPosition, 0));
            isLillyPadUp = true;
        }
    }

    public override IEnumerator OnWalkedOnByPlayer(Character player, Vector3 moveDirection)
    {
        yield return StartCoroutine(base.OnWalkedOnByPlayer(player, moveDirection));

        if (trappedCharacter == null && !isLillyPadUp)
        {
            CurrentPlayer = null;
            trappedCharacter = player;
            trappedCharacter.stuck = true;

            trappedCharacter.StartAnimation(Character.Animation.Hit);
            yield return StartCoroutine(LerpToPosition(trappedCharacter.transform, VisualPosition + Vector3.down * FallDistance, 1));
        }

    }

    public override void OnLeftByPlayer(Character player)
    {
        base.OnLeftByPlayer(player);
        if (isLillyPadUp && CurrentPlayer == null)
        {
            StartCoroutine(LerpToPosition(lillyPad.transform, VisualPosition + Vector3.down * FallDistance, 1));
            isLillyPadUp = false;
        }

    }

    public override IEnumerator OnRoundEnd(PlayerData[] allPlayers)
    {
        //Debug.Log("reseting water");

        if (trappedCharacter != null)
        {

            //if character is on an angle undo their last rotation
            if (trappedCharacter.transform.eulerAngles.y % 90 > 10 && trappedCharacter.transform.eulerAngles.y % 90 < 80)
            {
                trappedCharacter.transform.Rotate(Vector3.up, -trappedCharacter.lastRotation);
                trappedCharacter.lastRotation = 0;

                //if they are still on an angle fix to the closest rotation
                if (trappedCharacter.transform.eulerAngles.y % 90 != 0)
                {
                    Vector3 newRot = trappedCharacter.transform.eulerAngles;
                    newRot.y = Mathf.Round(newRot.y / 90) * 90;
                    trappedCharacter.transform.eulerAngles = newRot;
                }
            }


            StartCoroutine(LerpToPosition(trappedCharacter.transform, VisualPosition, 1));
            StartCoroutine(LerpToPosition(lillyPad.transform, VisualPosition, 1));

            if (CurrentPlayer != null)
            {
                yield return new WaitForSeconds(0.2f);
                yield return StartCoroutine(PushPlayOnTop());
            }
            else
            {
                yield return new WaitForSeconds(1);
                CurrentPlayer = trappedCharacter;
            }

            trappedCharacter.stuck = false;
            isLillyPadUp = true;
            trappedCharacter = null;

        }
        isFinished = true;

    }

    private IEnumerator PushPlayOnTop()
    {
        Direction[] possibleDirections = DirectionExtras.RandomOrder();

        for (int i = 0; i < 4; i++)
        {
            if (Block.isBlockAtPosition(position + possibleDirections[i].ToVector() + Vector3.up, 1, ~0))
                continue;

            yield return StartCoroutine(DoPush(trappedCharacter, possibleDirections[i].ToVector()));
            break;
        }

    }

    private IEnumerator LerpToPosition(Transform target, Vector3 endPos, float time)
    {
        Vector3 _startPos = target.position;

        float elapsedTime = 0;
        while (elapsedTime / time < 1)
        {

            target.position = Vector3.Lerp(_startPos, endPos, (elapsedTime / time));
            yield return new WaitForEndOfFrame();

            elapsedTime += Time.deltaTime;
        }

        target.position = endPos;
    }


}
