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

public class PlayerController : MonoBehaviour
{
    public GameManager gm;
    private float speed = 1000f;
    public bool isGrounded = false;

    public int playerNumber;
    private Rigidbody2D rb;
    private SpriteRenderer sr;

    public bool isInFrontOfStairs = false;
    public GameObject stairsInFront = null;
    public float verticalSpeed = 0;

    public bool isBringingItem = false;
    public GameObject broughtItem;

    public Sprite spriteFront;
    public Sprite spriteSide;
    public Sprite spriteBack;
    public Sprite damageSprite;

    public Sprite confusedSprite;


    public bool isInFrontOfShower = false;
    public Shower showerInFrontOfMe;
    public bool canMove = true;

    public int maxHealth = 10;
    public int currentHealth;

    public ProgressBar progressBar;
    public float timeToBlink = 2f;

    public bool isTakingDamage = false;

    public bool isInFrontOfGrabbableItem = false;
    public GameObject grabbableInFrontOfMe = null;

    public KeyCode left = KeyCode.LeftArrow;
    public KeyCode right = KeyCode.RightArrow;
    public KeyCode up = KeyCode.UpArrow;
    public KeyCode down = KeyCode.DownArrow;
    public KeyCode aButton = KeyCode.Space;

    // Start is called before the first frame update
    void Start()
    {
        currentHealth = maxHealth;
        rb = GetComponent<Rigidbody2D>();
        sr = GetComponent<SpriteRenderer>();

        UpdateHealthBar();


    }

    public void TakeDamage(int dmg)
    {
        currentHealth-=dmg;
        StartCoroutine(Blink(timeToBlink));

        if(currentHealth <= 0)
        {
            if( playerNumber == 1)
                gm.GameOver(2);

            if (playerNumber == 2)
                gm.GameOver(1);
        }


        UpdateHealthBar();
    }

    public void StopForAWhile()
    {
        canMove = false;
        sr.sprite = confusedSprite;

        Invoke("RestartMoving", 3f);

    }

    public void RestartMoving()
    {
        sr.sprite = spriteFront;
        canMove = true;
    }


    public void Heal()
    {
        currentHealth++;
        if (currentHealth >= maxHealth)
            currentHealth = maxHealth;

        UpdateHealthBar();
    }

    public void UpdateHealthBar()
    {
        progressBar.UpdateBar(currentHealth, maxHealth);
    }

    // Update is called once per frame
    void FixedUpdate()
    {

        Move();

        if(IsPressingDown())
        {

            if (isBringingItem && broughtItem != null && isGrounded)
            {
                CheckItem();
            }
            else
            {

                if (isInFrontOfGrabbableItem && grabbableInFrontOfMe != null)
                {
                    BringSomething(grabbableInFrontOfMe);
                }

                else if (isInFrontOfShower)
                {
                    if (showerInFrontOfMe != null)
                    {
                        if (!showerInFrontOfMe.isBeingUsed)
                        {
                            rb.velocity = Vector3.zero;
                            showerInFrontOfMe.playerUsingShower = GetComponent<PlayerController>();

                            showerInFrontOfMe.UseShower();

                            canMove = false;
                        }
                        else if (showerInFrontOfMe.isBeingUsed && !canMove)
                        {
                            showerInFrontOfMe.FinishShower();
                            canMove = true;

                        }
                    }

                }



            }
        }
    }


    public void CheckItem()
    {
        CheckPhon();
        CheckBanana();
        CheckOil();

        UseItem();

    }

    public void CheckPhon()
    {
        if( isInFrontOfShower && broughtItem.tag == "Phon" && showerInFrontOfMe.isBeingUsed )
        {
            showerInFrontOfMe.UsePhonOnShower(GetComponent<PlayerController>());

        }
    }

    public void CheckBanana()
    {
        if( broughtItem.tag == "Banana" )
        {
            GameObject spawnedBanana = Instantiate(broughtItem.GetComponent<GrabbableItem>().toBeSpawned);
            Vector3 pos = transform.position;
            pos.y -= 1.5f;
            spawnedBanana.transform.position = pos;
        }
    }

    public void CheckOil()
    {
        if (broughtItem.tag == "Oil")
        {
            GameObject spawnedOil = Instantiate(broughtItem.GetComponent<GrabbableItem>().toBeSpawned);
            Vector3 pos = transform.position;
            pos.y -= 2.7f;
            spawnedOil.transform.position = pos;
        }
    }

    public void UseItem()
    {
        isBringingItem = false;
        broughtItem = null;
        transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite = null;

    }

    public bool IsGoingDown()
    {
        if (Input.GetAxis("Vertical" + playerNumber) > 0.3f || Input.GetKey(down))
            return true;
        return false;
    }

    public bool IsPressing()
    {
        bool a = Input.GetButton("Action" + playerNumber) || Input.GetKeyDown(aButton);
        return a;
    }

    public bool IsPressingDown()
    {
        bool a = Input.GetButtonDown("Action" + playerNumber) || Input.GetKeyDown(aButton);
        return a;
    }

    public IEnumerator Blink(float timer)
    {
        canMove = false;
        isTakingDamage = true;
        sr.sprite = damageSprite;
        //canMove = false;
        while(timer > 0f)
        {
            sr.enabled = !sr.enabled;

            timer -= Time.deltaTime;

            yield return new WaitForFixedUpdate(); //WaitForSeconds(0.1f);
        }


        sr.sprite = spriteFront;
        sr.enabled = true;
        canMove = true;
        yield return null;
    }

    private void Move()
    {
        if(canMove)
        {
            float horizontalSpeed = 0;
            verticalSpeed = 0;
            if (isGrounded)
            {
                horizontalSpeed = Input.GetAxis("Horizontal" + playerNumber) * speed * Time.deltaTime;
                if (Input.GetKey(left)) {
                    horizontalSpeed = -1 * speed * Time.deltaTime;
                }
                if (Input.GetKey(right)) {
                    horizontalSpeed = 1 * speed * Time.deltaTime;
                }

            }




            if (horizontalSpeed > 0)
                transform.localScale = new Vector3(-1, 1, 1);
            else if (horizontalSpeed < 0)
                transform.localScale = new Vector3(1, 1, 1);
                
            if (isInFrontOfStairs)
            {
                /*
                if (Input.GetAxis("Vertical" + playerNumber) != 0)
                {
                    //transform.Translate(0, Input.GetAxis("Vertical" + playerNumber) * Time.deltaTime * 10f, 0);
                    transform.position += new Vector3(0, Input.GetAxis("Vertical" + playerNumber) * Time.deltaTime * 10f, 0);
                }
                */

                /*
                if (Input.GetAxis("Vertical" + playerNumber) != 0)
                {
                    Vector3 reachPosition = Vector3.zero;
                    float direction = 0;
                    if (Input.GetAxis("Vertical" + playerNumber) < -0.7f)
                    {
                        direction = 1;
                        reachPosition = stairsInFront.GetComponent<Stairs>().top.transform.position;
                        transform.position = stairsInFront.GetComponent<Stairs>().bottom.transform.position;
                    }
                    if (Input.GetAxis("Vertical" + playerNumber) > 0.7f )
                    {
                        direction = -1;
                        reachPosition = stairsInFront.GetComponent<Stairs>().bottom.transform.position;
                        transform.position = stairsInFront.GetComponent<Stairs>().top.transform.position;
                    }

                    if (reachPosition.x != 0 && reachPosition.y != 0)
                    {
                        horizontalSpeed = 0;
                        verticalSpeed = Time.deltaTime;
                        //transform.position = Vector3.MoveTowards(transform.position, reachPosition, verticalSpeed);
                        //transform.Translate(direction * Vector3.up * Time.deltaTime * verticalSpeed);
                        print(transform.position.y);

                    }
                }
                else
                {
                    verticalSpeed = 0;
                }
                */



                verticalSpeed = -Input.GetAxis("Vertical" + playerNumber) * speed * Time.deltaTime;

                if (Input.GetKey(up)) {
                    verticalSpeed = 1 * speed * Time.deltaTime;
                }else if (Input.GetKey(down)) {
                    verticalSpeed = -1 * speed * Time.deltaTime;
                }

                if (!isGrounded)
                    horizontalSpeed = 0;

                //if (verticalSpeed != 0)
                if (!isTakingDamage)
                    sr.sprite = spriteBack;

                if (Input.GetAxis("Vertical" + playerNumber) == 0)
                {
                    //SetConstraints();
                }
                else
                {
                    //UnsetConstraints();
                }

            }

            rb.velocity = new Vector3(horizontalSpeed, verticalSpeed, 0);

            transform.localEulerAngles = Vector3.zero;

            if (!isTakingDamage && !isInFrontOfStairs)
            {
                if (horizontalSpeed == 0)
                    sr.sprite = spriteFront;
                else
                    sr.sprite = spriteSide;
            }
        }

    }

    private void SetConstraints()
    {
        rb.constraints = RigidbodyConstraints2D.None;
        rb.constraints = RigidbodyConstraints2D.FreezeRotation;
        rb.constraints = RigidbodyConstraints2D.FreezePositionY;
    }

    private void UnsetConstraints()
    {
        rb.constraints = RigidbodyConstraints2D.None;
        rb.constraints = RigidbodyConstraints2D.FreezeRotation;
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Floor" && transform.position.y > collision.gameObject.transform.position.y )
        {
            isGrounded = true;
        }
    }

    private void OnCollisionStay2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Floor" && transform.position.y > collision.gameObject.transform.position.y)
        {
            isGrounded = true;
        }
    }

    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Floor")
        {
            isGrounded = false;
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Stairs")
        {
            isInFrontOfStairs = true;
            stairsInFront = collision.gameObject;
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Stairs")
        {
            //print(collision.gameObject.name);
            isInFrontOfStairs = false;
            stairsInFront = null;

        }
    }

    public void BringSomething(GameObject objectToBring)
    {
        isBringingItem = true;
        broughtItem = objectToBring;
        transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite = broughtItem.GetComponent<SpriteRenderer>().sprite;
        //broughtItem.transform.SetParent(transform);
        //broughtItem.transform.localPosition = Vector3.zero;
    }

}
