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

public class TentacleController : MonoBehaviour
{
    public enum TentacleState
    {
        NONE, Hidden, Rising, Normal, Hit, Hiding, DEAD
    }

    public TentacleState _state;

    public TentacleState State
    {
        set
        {
            if (_state == value)
            {
                return;
            }

            switch (value)
            {
                case TentacleState.Hidden:
                    var position = transform.position;
                    position.y = HIDDEN_POSITION_Y;
                    transform.position = position;

                    timeElapsedSinceLastAppearance = 0f;
                    floater.enabled = false;
                    floater.autoMoveSpeed = 0f;
                    floater.floatOffset = FLOATER_SHOW_TARGET_Y;
                    changeDirectionWhenRising = true;
                    break;
                case TentacleState.Rising:
                    AudioManager.Instance.PlayTentacleAppear();
                    floater.autoMoveSpeed = 0f;
                    floater.enabled = false;

                    if (transform.position.x < PlayerController.instance.transform.position.x && changeDirectionWhenRising)
                    {
                        GetComponent<SpriteRenderer>().flipX = true;
                    }

                    else if(transform.position.x > PlayerController.instance.transform.position.x && changeDirectionWhenRising)
                    {
                        GetComponent<SpriteRenderer>().flipX = false;
                    }

                    break;
                case TentacleState.Normal:
                    floater.enabled = true;
                    floater.floatOffset = FLOATER_SHOW_TARGET_Y;

                    if (transform.position.x < PlayerController.instance.transform.position.x && changeDirectionWhenRising)
                    {
                        floater.autoMoveSpeed = Mathf.Abs(speed);
                    }

                    else if (transform.position.x > PlayerController.instance.transform.position.x && changeDirectionWhenRising)
                    {
                        floater.autoMoveSpeed = Mathf.Abs(speed) * -1f;
                    }

                    break;
                case TentacleState.Hit:
                    timeElapsedSinceHit = 0f;
                    //floater.autoMoveSpeed = 0f;
                    break;
                case TentacleState.Hiding:
                    //floater.enabled = false;
                    //floater.autoMoveSpeed = 0f;
                    break;
                default:
                    break;
            }

            _state = value;
        }

        get
        {
            return _state;
        }
    }

    public float RISE_SPEED;
    public float RISE_PERIOD;
    public float RECOVERY_PERIOD;

    public Rigidbody2D body;
    public Animator animator;
    public Floater floater;
    public SpriteRenderer spriteRenderer;

    private float timeElapsedSinceLastAppearance;
    private float timeElapsedSinceHit;
    private float speed;
    private float HIDDEN_POSITION_Y = -6.3f - 1f;
    private float RISE_TARGET_Y = -1.6f -0.5f;
    private float FLOATER_HIDE_TARGET_Y = -1.5f;
    private float FLOATER_SHOW_TARGET_Y = 0.3f;
    private bool changeDirectionWhenRising = true;

    // Use this for initialization
    void Start()
    {
        speed = floater.autoMoveSpeed;
        State = TentacleState.Hidden;
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        switch (State)
        {
            case TentacleState.Hidden:
                timeElapsedSinceLastAppearance += Time.fixedDeltaTime;

                if (timeElapsedSinceLastAppearance >= RISE_PERIOD)
                {
                    Rise();
                }

                break;
            case TentacleState.Rising:
                break;
            case TentacleState.Normal:



                break;
            case TentacleState.Hit:
                timeElapsedSinceHit += Time.fixedDeltaTime;

                if (timeElapsedSinceHit >= RECOVERY_PERIOD)
                {
                    Recover();
                }
                break;
            case TentacleState.Hiding:
                break;
            default:
                break;
        }

        var cameraLeftSideAbscissa = Camera.main.transform.position.x - Camera.main.orthographicSize * Camera.main.aspect;
        var cameraRightSideAbscissa = Camera.main.transform.position.x + Camera.main.orthographicSize * Camera.main.aspect;

        if (transform.position.x < cameraLeftSideAbscissa - 2f || transform.position.x > cameraRightSideAbscissa + 2f)
        {
            State = TentacleState.Hidden;
        }
    }

    private void Recover()
    {
        StartCoroutine(Recover_Coroutine());
    }

    private IEnumerator Recover_Coroutine()
    {
        while (floater.floatOffset < FLOATER_SHOW_TARGET_Y - 0.05f)
        {
            floater.floatOffset = Mathf.Lerp(floater.floatOffset, FLOATER_SHOW_TARGET_Y, RISE_SPEED * Time.fixedDeltaTime);
            yield return new WaitForFixedUpdate();
        }

        changeDirectionWhenRising = false;
        State = TentacleState.Normal;
    }

    void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.gameObject.CompareTag("CannonBall"))
        {
            Debug.Log("TENTACLE CANNONBALL TRIGGER");
            if (State == TentacleState.Normal || State == TentacleState.Rising)
            {
                {
                    Hide();
                    TintHit();
                }
            }
        }
    }

//    void OnCollisionEnter2D(Collision2D collision)
//    {
//        if (State == TentacleState.Normal || State == TentacleState.Rising)
//        {
//            if (collision.gameObject.CompareTag("CannonBall"))
//            {
//                Hide();
//                TintHit();
//            }
//        }
//    }

    private void Hide()
    {
        StartCoroutine(Hide_Coroutine());
    }

    private void TintHit()
    {
        StopCoroutine("TintHit_Coroutine");
        StartCoroutine("TintHit_Coroutine");
    }

    private IEnumerator TintHit_Coroutine()
    {
        spriteRenderer.color = Color.red;

        var duration = 0.3f;
        var elapsedTime = 0f;

        while (elapsedTime <= duration)
        {
            elapsedTime += Time.deltaTime;
            var interpolant = elapsedTime / duration;

            spriteRenderer.color = Color.Lerp(Color.red, Color.white, interpolant);
            yield return new WaitForFixedUpdate(); 
        }

        spriteRenderer.color = Color.white;
    }

    private IEnumerator Hide_Coroutine()
    {
        State = TentacleState.Hiding;

        while (floater.floatOffset > FLOATER_HIDE_TARGET_Y + 0.05f)
        {
            floater.floatOffset = Mathf.Lerp(floater.floatOffset, FLOATER_HIDE_TARGET_Y, RISE_SPEED * Time.fixedDeltaTime);
            yield return new WaitForFixedUpdate();
        }

        State = TentacleState.Hit;
    }

    private void Rise()
    {
        StartCoroutine(Rise_Coroutine());
    }

    private IEnumerator Rise_Coroutine()
    {
        State = TentacleState.Rising;

        var cameraLeftSideAbscissa = Camera.main.transform.position.x - Camera.main.orthographicSize * Camera.main.aspect;
        transform.position = new Vector2(Random.Range(cameraLeftSideAbscissa, -cameraLeftSideAbscissa), HIDDEN_POSITION_Y);

        var riseTarget = transform.position;
        riseTarget.y = RISE_TARGET_Y;

        while (transform.position.y < RISE_TARGET_Y - 0.05f)
        {
            transform.position = Vector2.Lerp(transform.position, riseTarget, RISE_SPEED * Time.fixedDeltaTime);
            yield return new WaitForFixedUpdate();
        }

        State = TentacleState.Normal;
    }
}
