using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class PlayerController : MonoBehaviour
{
    #region ATTRIBUTES
    public PlayerInput playerInput;

    public float movSpeed = 0;
    public float rotSpeed = 0;

    public Light myLight;

    public Color minColor, maxColor;

    public float colorSpeed = 2;

    private bool pending = false;

    public float advance = 0;
    public float limit = 20;

    bool crashed = false;
    new Rigidbody rigidbody;

    public LayerMask[] othersMask;

    public float minShere = 1.0f, maxSphere = 5.0f;
    public float minDistance = 11;

    public new SmartCamera camera;

    public static List<PlayerController> players;

    public GameObject bulletPrefab;
    public Transform bulletOrigin;

    public int lives = 3;
    public int livesUsed = 0;

    public AudioSource source;
    public AudioClip[] clip;

    public float shieldRate = 4f;
    public float fireRate = 0.3f;
    bool canShoot = true;
    bool canUseShield = true;
    public string terrainTag = "Terrain";

    public GameObject shieldObject;
    public LayerMask bulletMask;
    public float shieldRadius = 5;
    public float shieldDuration = 1;

    public Image lifeUI, shieldUI, shotUI, lightUI;

    #endregion



    void Start()
    {
        rigidbody = GetComponent<Rigidbody>();
        this.tag = "Player" + (playerInput.realIndex + 1);
        camera.SetPlayer(playerInput.realIndex + 1);
        players.Add(this);

        //StartCoroutine(UpdateMethod());
    }

    IEnumerator ColdDownShot()
    {
        shotUI.color = new Color(shotUI.color.r, shotUI.color.g, shotUI.color.b, 0.3f);
        canShoot = false;
        yield return new WaitForSeconds(fireRate);
        canShoot = true;
        shotUI.color = new Color(shieldUI.color.r, shotUI.color.g, shotUI.color.b, 0.3f);
    }

    IEnumerator ColdDownShield()
    {
        shieldUI.color = new Color(shieldUI.color.r, shieldUI.color.g, shieldUI.color.b, 0.3f);
        canUseShield = false;
        yield return new WaitForSeconds(shieldRate);
        canUseShield = true;
        shieldUI.color = new Color(shieldUI.color.r, shieldUI.color.g, shieldUI.color.b, 1);
    }

    IEnumerator ShowMesh()
    {
        shieldObject.SetActive(true);
        yield return new WaitForSeconds(shieldDuration);
        shieldObject.SetActive(false);
    }

    public bool Dead {
        get{ return livesUsed>=lives; }
    }

    private void Update()
    {
        lifeUI.fillAmount = 1-(float)(livesUsed > 0 ? ((float)livesUsed / (float)lives) : 0f);
        if (crashed || livesUsed >= lives)
        {
            GameOver();
        }
        else
        {
            var inputY = (playerInput.useKeyboard ? Input.GetAxis("Vertical") : GamepadInput.GamePad.GetAxis(GamepadInput.GamePad.Axis.LeftStick, playerInput.controlIndex).y);
            if (inputY < 0)
                inputY /= 2.0f;
            var inputX = -1 * (playerInput.useKeyboard ? Input.GetAxis("Horizontal") : GamepadInput.GamePad.GetAxis(GamepadInput.GamePad.Axis.LeftStick, playerInput.controlIndex).x);

            rigidbody.velocity = transform.TransformDirection(new Vector3(0, 1, 0)) * inputY * movSpeed;
            transform.Rotate(0, 0, inputX * rotSpeed * Time.deltaTime);

            if (((playerInput.useKeyboard && Input.GetKeyDown(KeyCode.Space)) || (!playerInput.useKeyboard && GamepadInput.GamePad.GetButtonDown(GamepadInput.GamePad.Button.A, playerInput.controlIndex))) && !pending)
            {
                lightUI.color = new Color(lightUI.color.r, lightUI.color.g, lightUI.color.b, 0.3f);
                pending = true;
                advance = 0;
                myLight.DOColor(maxColor, colorSpeed).SetDelay(0).OnComplete(() =>
                {
                    var others = Physics.SphereCastAll(transform.position, maxSphere, Vector3.up);
                    bool found = false;
                    for (int i = 0; i < others.Length; i++)
                    {
                        if (!others[i].collider.gameObject.CompareTag(tag) && others[i].collider.gameObject.tag.Contains("Player"))
                        {
                            found = true;
                            camera.AddTreckedPlayer(int.Parse(others[i].collider.gameObject.tag.Replace("Player", "")));
                        }
                    }
                    if (found)
                        source.PlayOneShot(clip[1]);
                    else
                        source.PlayOneShot(clip[2]);

                    myLight.DOColor(minColor, colorSpeed).SetDelay(colorSpeed * 1.5f).OnComplete(() =>
                    {
                        pending = false;
                        lightUI.color = new Color(lightUI.color.r, lightUI.color.g, lightUI.color.b, 1);

                        Sequence mySequence = DOTween.Sequence();

                        mySequence.PrependInterval(0.5f).OnComplete(() =>
                        {
                            camera.SetPlayer(playerInput.realIndex + 1);
                        });
                    });
                });
            }
            if (((playerInput.useKeyboard && Input.GetKeyDown(KeyCode.Z)) || (!playerInput.useKeyboard &&
                GamepadInput.GamePad.GetButtonDown(GamepadInput.GamePad.Button.B, playerInput.controlIndex))) &&
                camera.IsWatchinOther() && canShoot)
            {
                StartCoroutine(ColdDownShot());
                source.PlayOneShot(clip[0]);
                var go = Instantiate(bulletPrefab, bulletOrigin.position, bulletOrigin.rotation);
                var fd = go.GetComponent<Rigidbody>();
                fd.velocity = go.transform.right * 12;
                Destroy(go, 2);
            }
            if (((playerInput.useKeyboard && Input.GetKeyDown(KeyCode.X)) || (!playerInput.useKeyboard &&
                GamepadInput.GamePad.GetButtonDown(GamepadInput.GamePad.Button.X, playerInput.controlIndex))) &&
                canUseShield)
            {
                StartCoroutine(ColdDownShield());
                source.PlayOneShot(clip[3]); /*Poner el sonido del escudo */
                var others = Physics.SphereCastAll(transform.position, shieldRadius, Vector3.up, bulletMask);
                for (int i = 0; i < others.Length; i++)
                {
                    if (others[i].collider.CompareTag("Bullet"))
                        Destroy(others[i].collider.gameObject);
                }
                StartCoroutine(ShowMesh());
            }
            if (pending)
            {
                advance += Time.deltaTime * 30;
                myLight.spotAngle = Mathf.Lerp(10, 70, advance / limit);
            }
            for (int i = 0; i < players.Count; i++)
            {
                if (players[i] != this)
                {
                    if (!camera.IsTracked(players[i].playerInput.realIndex + 1))
                        if (Vector3.Distance(transform.position, players[i].transform.position) < minDistance)
                        {
                            camera.AddPlayer(players[i].playerInput.realIndex + 1);
                        }
                        else
                        {
                            camera.RemovePlayer(players[i].playerInput.realIndex + 1);
                        }
                }
            }




        }
    }

    IEnumerator Refresh()
    {
        crashed = true;
        yield return new WaitForSeconds(0.5f);
        crashed = false;
        rigidbody.drag = 10.0001f;
        rigidbody.angularDrag = 10.0001f;
    }

    void OnCollisionEnter(Collision c)
    {
        if (!rigidbody)
            return;
        rigidbody.drag = 0.0001f;
        rigidbody.angularDrag = 0.0001f;
        rigidbody.AddForce(c.contacts[0].normal * 100);
        StartCoroutine(Refresh());
        livesUsed++;

        if (!c.collider.CompareTag(terrainTag) && !c.collider.tag.Contains("Player"))
        {
            Destroy(c.collider.gameObject);
            source.PlayOneShot(clip[4]);
        }
    }

    #region INGAME METHODS
    public void EnableCamera(bool active)
    {
        //disable camera
        camera.enabled = active;
    }

    /// <summary>
    /// Game Over player
    /// </summary>
    public void GameOver()
    {
        //Show Game Set Window
    }
    #endregion
}
