using UnityEngine;

public class InputHandler : MonoBehaviour
{
    public float MaxPressTime = 2f;

    public float MinDistanceToPlayer = 5f;

    public WaveCreationIndicator WaveCreationIndicator;

    private float _currentTimer;
    private bool _handleTimer;
    private Vector2 _inputPosition;

    private Transform _player;
    
    #region Unity

    private void Awake()
    {
        _player = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
    }

    private void Update()
    {
#if UNITY_ANDROID

        if (Input.touchCount == 0)
        {
            _handleTimer = false;
        }
        else if (Input.GetTouch(0).phase == TouchPhase.Began)
        {
            if (RaycastChecker(Input.GetTouch(0).position))
            {
                Debug.Log("Position is not valid!");
                return;
            }
            
            _inputPosition = Input.GetTouch(0).position;
            StartTimer();
        }
        else if (Input.GetTouch(0).phase == TouchPhase.Canceled ||
                 Input.GetTouch(0).phase == TouchPhase.Ended)
        {
            EndTimer();
        }

#else

        if (Input.GetMouseButtonDown(0))
        {
            Ray inputRay = new Ray(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.forward);
            RaycastHit rayHit;
            
            if (Physics.Raycast(inputRay, out rayHit))
            {
                if (rayHit.collider.CompareTag("Player"))
                {
                    //Debug.Log("Clicked on player.");
                    return;
                }

                if (rayHit.collider.CompareTag("Background"))
                {
                    float distance = Vector3.Distance(rayHit.point, _player.transform.position);

                    if (distance <= MinDistanceToPlayer)
                    {
                        //Debug.Log("Distance: " + distance);
                        return;
                    }
                }
            }

            _inputPosition = Input.mousePosition;
            StartTimer();
        }

        if (Input.GetMouseButtonUp(0))
        {
            EndTimer();
        }

#endif

        HandleTimer();
    }

#endregion

    private void HandleTimer()
    {
        if (!_handleTimer)
            return;

        _currentTimer += Time.deltaTime;        

        if (WaveCreationIndicator != null)
            WaveCreationIndicator.UpdateScale(MaxPressTime, _currentTimer);
    }

    private void StartTimer()
    {
        Vector2 mouseWorldPosition = Camera.main.ScreenToWorldPoint(_inputPosition);

        WaveCreationIndicator.StartIndicator(mouseWorldPosition);
        WaveCreationIndicator.gameObject.SetActive(true);

        _currentTimer = 0;
        _handleTimer = true;

        //_inputPosition = Input.mousePosition;        
    }

    private void EndTimer()
    {
        if (!_handleTimer)
        {
            //Debug.Log("Dont create a new wave!");
            return;
        }

        _handleTimer = false;
        _currentTimer = Mathf.Clamp(_currentTimer, 0, MaxPressTime);

        WaveCreationIndicator.gameObject.SetActive(false);

        Vector2 mouseWorldPosition = Camera.main.ScreenToWorldPoint(_inputPosition);
        WaveCreation.Instance.CreatePlayerWave(mouseWorldPosition, _currentTimer);               
    }

    /// <summary>
    /// Checks if the input position is a valid point to spawn
    /// a new wave.
    /// </summary>
    /// <param name="position">RAW DATA for input position</param>
    /// <returns>TRUE - Position is not valid.</returns>
    private bool RaycastChecker(Vector3 position)
    {
        Ray inputRay = new Ray(Camera.main.ScreenToWorldPoint(position), Vector3.forward);
        RaycastHit rayHit;

        if (Physics.Raycast(inputRay, out rayHit))
        {
            if (rayHit.collider.CompareTag("Player"))
            {
                //Debug.Log("Clicked on player.");
                return true;
            }

            if (rayHit.collider.CompareTag("Background"))
            {
                float distance = Vector3.Distance(rayHit.point, _player.transform.position);

                if (distance <= MinDistanceToPlayer)
                {
                    //Debug.Log("Distance: " + distance);
                    return true;
                }
            }
        }

        return false;
    }
}