﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayerOne : MonoBehaviour
{

    public float speed; //Velocidade do player
    public float jumpForce; //Força do pulo
    private float moveInput; //Verifica se o player está com as setas de direção ativadas


    private float inputHorizontal;
    private float inputVertical;
    public float distance;
    public LayerMask whatIsLadder;
    private bool isClimbing;
    public int upspeed;

    private Rigidbody2D rb; //rigidbody do player

    private bool facingRight = true; //Verifica se o player esta virado para a direita

    private bool isGrounded; //Verifica se o player está no chão
    public Transform groundCheck; //Objeto checador de colisão com o chão
    public float checkRadius; //Definir raio do circulo
    public LayerMask whatIsGround; //Layer para verificar oque é chão

    private int extraJumps; //Valor de pulos extras

    public int life = 10;
    private bool dead = false;
    private float damageTime = 2;
    private bool invincible = false;

    private float nextFire; //Controla quando pode atirar denovo
    private int bullets; //balas
    private float fireRate = 0.5f; //Tempo entre tiros
    public bool canFire = true;

    public GameObject bulletPrefab;
    public Transform shotSpawner;
    public Slider healthBar;





    public float dashSpeed; //Velocidade do Dash
    private float dashTime; //Tempo para terminar o dash
    public float startDashTime; //Tempo que o dash vai começar 
    private int direction; //direção do dash

    public Animator animator; //Animator será animator
    public AudioSource pulo;



    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        dashTime = startDashTime; //Tempo do dash sera o mesmo que o tempo de iniciar o dash
        pulo = GetComponent<AudioSource>();

    }

    void FixedUpdate() //Usado para gerenciar toda a física relacionada a aspectos do jogo
    {
        healthBar.value = life;

        if (dead == false)
        {
            if (life == 0)
            {
                isDead();
            }

            isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius); //vai se criar um circulo (tamanho definido pelo raio) na posição do groundcheck (pé do player)

            moveInput = Input.GetAxis("Horizontal"); //move input vai receber se o player esta apertando direita pu esquerda
            rb.velocity = new Vector2(moveInput * speed, rb.velocity.y); //Velocidade do rigidbody vai receber a direção multiplicado pela velocidade no eixo X, no eixo Y vai se manter no estado atual.
            animator.SetFloat("Speed", Mathf.Abs(moveInput));
            animator.speed = 1;

            //---------------------------------------------DASH V --------------------------------------------------------------

            if (direction == 0) //Se direction for 0..
            {
                if (Input.GetKeyDown(KeyCode.LeftArrow)) //Se o player apertar a seta esquerda..
                {
                    direction = 1; //direction será 1
                    facingRight = false;
                    Flip(facingRight);

                }
                else if (Input.GetKeyDown(KeyCode.RightArrow)) //Se o player apertar a seta para direita..
                {
                    direction = 2; //Direction será 2
                    facingRight = true;
                    Flip(facingRight);

                }
                /*else if (Input.GetKeyDown(KeyCode.UpArrow)) //Se o player apertar a seta para cima..
                {
                direction = 3; //Direction será 3
                }*/
                else if (Input.GetKeyDown(KeyCode.DownArrow)) //Se o player apertar a seta para baixo..
                {
                    direction = 4; //Direction será 4
                }
            }
            else //Se não..
            {
                if (dashTime <= 0) //Se o tempo de dash for menor ou igual a 0..
                {
                    direction = 0; //Direction será 0
                    dashTime = startDashTime; //Tempo do dash será o tempo do dash inicial
                    rb.velocity = Vector2.zero;
                    animator.SetBool("Dash", false);

                }
                else //Se não..
                {
                    dashTime -= Time.deltaTime; //Tempo do dash diminuirá..

                    if (direction == 1) //Se direction for igual a 1..
                    {
                        rb.velocity = Vector2.left * dashSpeed; //velocidade do rigidybody  vai acelerar pelo valor de dashSpeed para a esquerda
                        animator.SetBool("Dash", true);  // chama o trigger shoot do animator

                    }
                    else if (direction == 2) //Se direction for igual a 2..
                    {
                        rb.velocity = Vector2.right * dashSpeed; //velocidade do rigidybody  vai acelerar pelo valor de dashSpeed para a direita
                        animator.SetBool("Dash", true);


                    }
                    else if (direction == 3) //Se direction for igual a 3..
                    {
                        rb.velocity = Vector2.up * dashSpeed; //velocidade do rigidybody  vai acelerar pelo valor de dashSpeed para cima
                    }
                    else if (direction == 4) //Se direction for igual a 4..
                    {
                        rb.velocity = Vector2.down * dashSpeed; //velocidade do rigidybody  vai acelerar pelo valor de dashSpeed para baixo
                    }
                }
            }

            //---------------------------------------------DASH ^ --------------------------------------------------------------

            //---------------------------------------------Escada---------------------------------------------------------------
            RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, Vector2.up, distance, whatIsLadder);

            if (hitInfo.collider != null)
            {
                if (Input.GetKey(KeyCode.UpArrow))
                {
                    isClimbing = true;
                    animator.SetBool("isClimbing", true);
                    animator.speed = 1;
                }

                else if (Input.GetKey(KeyCode.DownArrow))
                {

                    isClimbing = true;
                    animator.SetBool("isClimbing", true);
                    animator.speed = 1;
                }

                else
                {
                    animator.speed = 0;
                }

            }
            else
            {
                isClimbing = false;
            }

            if (isClimbing == true)
            {
                inputVertical = Input.GetAxisRaw("Vertical");
                rb.velocity = new Vector2(rb.velocity.x, inputVertical * upspeed);
                rb.gravityScale = 0;
            }
            else
            {
                rb.gravityScale = 5;
                animator.SetBool("isClimbing", false);
            }




            if (moveInput > 0) //Se o player estiver virado para a esquerda e a velocidade de movimento for positiva..
            {
                facingRight = true;
                Flip(facingRight); //Vira sprite para Direita
            }
            else if (moveInput < 0) //Se o player virado para a direita e a velocidade de movimento for negativa..
            {
                facingRight = false;
                Flip(facingRight); //Vira sprite para esquerda
            }
        }
    }
    void Update()
    {
        if (life >= 4)
        {
            life = 3;
        }

        if (dead == false)
        {


            if (isGrounded == true) //Se o player estiver no chão..
            {
                extraJumps = 1; //pulo extra sera 1
                animator.SetBool("isJumping", false);
            }

            if (Input.GetKeyDown(KeyCode.W) && extraJumps > 0) // Se o player estiver com a tecla de pular pressionada e tiver pulos extras..
            {
                rb.velocity = Vector2.up * jumpForce; //rigidybody vai receber o valor do jumpforce no sentido Y.
                extraJumps--; //player tera -1 pulo extra
                animator.SetBool("isJumping", true);
                pulo.Play();
                animator.speed = 1;

            }
            else if (Input.GetKeyDown(KeyCode.W) && extraJumps == 0 && isGrounded == true) //se o player pressionar a tecla de pulo e não tiver pulo extra e estiver no chão
            {
                rb.velocity = Vector2.up * jumpForce; //rigidybody vai receber o valor do jumpforce no sentido Y.
                animator.SetBool("isJumping", true);
                animator.speed = 1;
            }
        }
    }
    void Flip(bool right) //Função Virar Sprite 
    {
        //facingRight = !facingRight;  Quando a função ser executada mudara o estado atual da lado que o player esta virado
        Vector3 Scaler = transform.localScale;
        if (right)
        {
            Scaler.x = Mathf.Abs(Scaler.x);
        }
        else
        {
            Scaler.x = Mathf.Abs(Scaler.x) * -1;
        }
        transform.localScale = Scaler;
        Debug.Log("flipei");
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.tag == "Enemy")
        {
            if (!invincible)
            {
                life--;
                rb.AddForce(new Vector3(-5000, 0));
                invincible = true; // makes this whole function unusable since invincible is no longer false
                StartCoroutine(Pisca());
                Invoke("resetInvulnerability", 2);
            }
        }

        if (other.gameObject.tag == "Boss")
        {
            if (!invincible)
            {
                life--;
                rb.AddForce(new Vector3(-5000, 0));
                invincible = true; // makes this whole function unusable since invincible is no longer false
                StartCoroutine(Pisca());
                Invoke("resetInvulnerability", 2);
            }
        }

        if (other.gameObject.tag == "Chest")
        {
            life++;

        }

        if (other.gameObject.tag == "Hole")
        {
            life = -100;
            isDead();

        }
    }

    void resetInvulnerability()
    {
        invincible = false;
    }

    IEnumerator Pisca()
    {

        for (float i = 0; i < damageTime; i += 0.2f)
        {
            GetComponent<SpriteRenderer>().enabled = false;
            yield return new WaitForSeconds(0.1f);
            GetComponent<SpriteRenderer>().enabled = true;
            yield return new WaitForSeconds(0.1f);
        }
    }


    void isDead()
    {
        if (life <= 0)
        {
            dead = true;
            speed = 0;
            animator.SetBool("isDeath", true);
            Destroy(gameObject);
            SceneManager.LoadScene("Esgoto");
        }
    }

    public void atirar()
    {
        GameObject tempBullet = Instantiate(bulletPrefab, shotSpawner.position, shotSpawner.rotation);//Cria o objeto bullet na posição e rotação do bullet spawner
        if (!facingRight) // Se não estiver olhando para direita e não estiver olhando para cima..
        {
            tempBullet.transform.eulerAngles = new Vector3(0, 0, 180);// Cria o objeto bullet na rotação 180
        }
        animator.SetBool("Atirando", false);
    }

}
