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

public class ProjectileOld : MonoBehaviour
{

    [SerializeField]
    private Detection _detectionLinked;

    [SerializeField]
    private bool straightProjectile = false;

    private float _time = 0f;
    private float _duration = 1f;

    [SerializeField]
    private float _angle = 10f; //Default
    [SerializeField]
    private float _speed = 2f; //Default

    private Vector2 _vectorStart;
    private Vector2 _vectorEnd;

    private int _damage;
    private float _enemySpeed;
    private Entity _target;

    private Rigidbody2D _rigidbodyProjectile;
    private float _initialX;
    private float _initialY;
    private float _destinationX;
    private float _destinationY;
    private float _enemyPosY = 0f;
    private float _speedTime = 0f;

    private float _initialXDistance;
    private float _initialYDistance;

    private void Start()
    {
        _rigidbodyProjectile = GetComponent<Rigidbody2D>();
        _initialX = transform.position.x;
        _initialY = transform.position.y;
        _destinationX = _vectorEnd.x - _initialX - _enemySpeed;
        _destinationY = _vectorEnd.y - _initialY;

        _detectionLinked.gameObject.GetComponent<Detection>().EntityLinked = _target;
        _detectionLinked.gameObject.GetComponent<Detection>().ProjectileDamage = _damage;

        _initialXDistance = Mathf.Abs(_initialX - _destinationX);
        _initialYDistance = Mathf.Abs(_initialY - _destinationY);
    }

    private void Update()
    {
        if (straightProjectile)
        {

            transform.position = Vector2.Lerp(new Vector2(_initialX, _initialY),
                new Vector2(_vectorEnd.x, _vectorEnd.y), _time / _duration);

            DetStraigthArrowAngle();

            //TODO: Implementer cette methode pour mieux faire fonctionner le projectile lorsque possible.
            //transform.LookAt(VectorEnd, Vector3.forward);

            _time += Time.deltaTime;

            if (transform.position.x >= _vectorEnd.x)
            {
                ApplyEffects();
                Destroy(this.gameObject);
            }
            return;
        }

        float x = _speedTime;
        float y = (_angle * -Mathf.Pow(x, 2) + _destinationX * x);

        transform.position = new Vector2(_initialX + x * _angle, _initialY + y);

        // Move projectile angle according to distance with target
        float lerpStep = (_destinationX - transform.position.x) / _initialXDistance;
        float angle = Mathf.Lerp(-100f, 45f, lerpStep);
        transform.eulerAngles = new Vector3(0, 0, angle);

        _speedTime += _speed * Time.deltaTime;

        if (y < 0)
        {
            Destroy(this.gameObject);
        }
    }

    protected virtual void DetStraigthArrowAngle()
    {

        if (_target != null) _enemyPosY = _target.Position.y;

        float angleX = (_destinationX) / _initialXDistance;
        float angleY = (_destinationY) / _initialYDistance;

        //Obtenir la difference entre la position Y du chateau et de l'ennemie.
        float diffY = transform.position.y - _enemyPosY;

        //D'abord,on regarde si l'ennemi et l'unite sont a la meme hauteur.
        //Si ce n'est pas le cas, on modifie l'angle de la fleche. Sinon, on ne change rien.
        if (diffY >= 0.1 || diffY <= -0.1)
        {

            float lerpStepS;

            //Ensuite, on regarde la position entre l'ennemi et l'unite.
            //Si cette distance est plus petite qu'un certain nombre, on utilise un calcul differents
            //pour determine l'angle que la fleche doit prendre.
            if (angleX > 0.23) lerpStepS = Mathf.Rad2Deg * Mathf.Atan(angleX / angleY);

            //Si la position est negative, on utilise un calcul different pour determiner l'angle.
            //(Il faudra tester si ca marche lorsque le chateau pourrait tirer en arriere).
            else if (angleX >= 0) lerpStepS = Mathf.Rad2Deg * Mathf.Atan(angleY / angleX);

            //Calcul utilise pour tenter de mieux faire fonctionner l'angle de la fleche lorsque l'ennemi est 
            //proche de l'unite.
            else
            {

                lerpStepS = -Mathf.Rad2Deg * Mathf.Atan(angleY / angleX);
            }

            float angleS = Mathf.Lerp(lerpStepS, 0, 0);
            transform.eulerAngles = new Vector3(0, 0, angleS);
        }
    }

    // applies effects on hit
    protected virtual void ApplyEffects() { }

    //Getter and Setter
    public float EnemySpeed
    {
        get { return _enemySpeed; }
        set { _enemySpeed = value; }
    }

    public float Angle
    {
        get { return _angle; }
        set { _angle = value; }
    }

    public float Speed
    {
        get { return _speed; }
        set { _speed = value; }
    }

    public int Damage
    {
        get { return _damage; }
        set { _damage = value; }
    }

    public Vector2 VectorStart
    {
        get { return _vectorStart; }
        set { _vectorStart = value; }
    }

    public Vector2 VectorEnd
    {
        get { return _vectorEnd; }
        set { _vectorEnd = value; }
    }

    public Entity Target
    {
        get { return _target; }
        set { _target = value; }
    }
}
