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

public class SharkController : MonoBehaviour
{
    public Rigidbody2D body;
    public SpriteRenderer spriteRenderer;
    public Animator animator;
    public Floater floater;

    [Header("Swimming")]
    public float swimSpeed;
    public float swimFloatOffset;

    [Header("Attacking")]
    public float attackSpeed;
    public float attackTriggerDistance;
    public float attackFloatOffset;

    private float attackPosition;
    private bool hasAttacked;

    #region SharkState

    private enum SharkState
    {
        NONE,
        SWIMMING,
        ATTACKING,
        DEAD
    }

    private SharkState _state;

    private SharkState State
    {
        get { return _state; }
        set
        {
            if (_state == value)
            {
                return;
            }

            animator.ResetTrigger("Idle");
            animator.ResetTrigger("Death");

            _state = value; 
            switch (_state)
            {
                case SharkState.SWIMMING:
                    floater.originalAngle = 90f;
                    floater.enableFloating = true;
                    floater.autoMoveSpeed = swimSpeed;
                    break;

                case SharkState.ATTACKING:
                    floater.originalAngle = 0f;
                    floater.enableFloating = true;
                    floater.autoMoveSpeed = attackSpeed;
                    AudioManager.Instance.PlaySharkAppear();
                    break;

                case SharkState.DEAD:
                    floater.originalAngle = 0f;
                    floater.enableFloating = false;
                    floater.autoMoveSpeed = 0f;
                    floater.autoMove = false;
                    floater.alignToWaves = false;
                    body.gravityScale = 1f;
                    animator.SetTrigger("Death");
                    DestroyDelayed();
                    break;
            }
        }
    }

    #endregion


    void Start()
    {
        State = SharkState.SWIMMING;
    }

    void Update()
    {
        var distanceFromPlayer = Mathf.Abs(transform.position.x - GameManager.Instance.player.transform.position.x);
        var distanceFromAttackPosition = Mathf.Abs(transform.position.x - attackPosition);

        switch (State)
        {
            case SharkState.SWIMMING:
                Dive(hasAttacked ? distanceFromAttackPosition : distanceFromPlayer);

                // Trigger attack
                if (distanceFromPlayer < attackTriggerDistance && !hasAttacked)
                {
                    attackPosition = GameManager.Instance.player.transform.position.x;
                    hasAttacked = true;
                    State = SharkState.ATTACKING;
                }
                break;

            case SharkState.ATTACKING:
                Attack(distanceFromAttackPosition);

                // Go back to swimming
                if (distanceFromAttackPosition > attackTriggerDistance)
                {
                    State = SharkState.SWIMMING;
                }
                break;
        }

        if (transform.position.x < -16f)
        {
            Destroy(gameObject);
        }
    }

    void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.gameObject.CompareTag("CannonBall"))
        {
            Debug.Log("SHARK CANNONBALL TRIGGER");
            if (State == SharkState.ATTACKING)
            {
                State = SharkState.DEAD;
            }
        }
    }

    private void Dive(float currentDistance)
    {
        var startDistance = 5f;
        var endDistance = 3f;
        var length = Mathf.Abs(startDistance - endDistance);

        var interpolant = Mathf.Clamp(startDistance - currentDistance, 0f, length) / length;
        //Debug.Log("Dive: " + " interpolant = " + interpolant + " = Mathf.Clamp(" + startDistance + " - " + distanceFromPlayer + ", " + 0f + ", " + length + ") / " + length + ")");
        floater.floatOffset = Mathf.Lerp(swimFloatOffset, -spriteRenderer.bounds.extents.x, interpolant);
    }

    private void Attack(float currentDistance)
    {
        var startDistance = 3f;
        var endDistance = 1f;
        var length = Mathf.Abs(startDistance - endDistance);

        var interpolant = Mathf.Clamp(startDistance - currentDistance, 0f, length) / length;
        //Debug.Log("Attack: " + " interpolant = " + interpolant + " = Mathf.Clamp(" + startDistance + " - " + distanceFromPlayer + ", " + 0f + ", " + length + ") / " + length + ")");
        floater.floatOffset = Mathf.Lerp(-spriteRenderer.bounds.extents.y, attackFloatOffset, interpolant);
    }

    private void DestroyDelayed()
    {
        Destroy(gameObject, 3f);
    }
}
