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

public class PlayerController : MonoBehaviour
{

    public float speed = 5;

    public int extraJumps = 2;
    private int extraJumpsValue;

    float moveInput;

    bool facingRight = true;


    bool isGrounded;

    Collider2D hitObject;
    
    Rigidbody2D rb;

    [Header("Jump Force Settings")]
    public float defaultJumpForce = 5;
    public float minJumpForce = 0;
    public float maxJumpForce = 50;

    [Header("Player Speed Settings")]
    public float minSpeed;
    public float maxSpeed;

    [Header("Other Settings")]
    EntityAttributes entity;

    Vector2 startPosition;

    //groundcheck
    public Transform rayLeft;
    public Transform rayRight;
    public Transform rayMiddle;
    public float groundCheckRayDistance = 0.1f;

    //jumattack
    public Transform jumpattack;
    public Vector2 jumpattackSize = new Vector2(1, 0.5f);

    public GameObject deathParticle;

    public AudioClip JumpSound;
    public AudioClip deathSound;

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        extraJumpsValue = extraJumps;

        entity = GetComponent<EntityAttributes>();


    }
    
    void Start()
    {
        startPosition = transform.position;
    }

    
    void Update()
    {
        moveInput = Input.GetAxis("Horizontal");



        //raycast for grounded and jumpattack
        RaycastHit2D hitLeft = Physics2D.Raycast(rayLeft.position, -Vector2.up, 1f);
        RaycastHit2D hitRight = Physics2D.Raycast(rayRight.position, -Vector2.up, 1f);
        RaycastHit2D hitMiddle = Physics2D.Raycast(rayMiddle.position, -Vector2.up, 1f);

        //grounded
        if (hitLeft.collider != null && hitLeft.collider.gameObject.layer == 8 && hitLeft.distance <= groundCheckRayDistance)
        {
            isGrounded = true;
            hitObject = hitLeft.collider;
            MovingPlatform();
        }
        else if (hitRight.collider != null && hitRight.collider.gameObject.layer == 8 && hitRight.distance <= groundCheckRayDistance)
        {
            isGrounded = true;
            hitObject = hitRight.collider;
            MovingPlatform();
        }
        else if (hitMiddle.collider != null && hitMiddle.collider.gameObject.layer == 8 && hitMiddle.distance <= groundCheckRayDistance)
        {
            isGrounded = true;
            hitObject = hitMiddle.collider;
            MovingPlatform();
        }else
        {
            isGrounded = false;
            this.transform.parent = null;
        }

        ////jumpattack
        //if (hitLeft.collider != null && hitLeft.collider.CompareTag("Enemy") && hitLeft.distance <= jumpAttackOffset)
        //{
        //    DoDamage(hitLeft.collider);
        //}
        //else if (hitRight.collider != null && hitRight.collider.CompareTag("Enemy") && hitRight.distance <= jumpAttackOffset)
        //{
        //    DoDamage(hitRight.collider);
        //}
        //else if (hitMiddle.collider != null && hitMiddle.collider.CompareTag("Enemy") && hitMiddle.distance <= jumpAttackOffset)
        //{
        //    DoDamage(hitMiddle.collider);
        //}


        //face direction
        if (facingRight == false && moveInput > 0)
        {
            Flip();

        }
        else if (facingRight == true && moveInput < 0)
        {
            Flip();

        }


        if (isGrounded == true)
        {
            extraJumps = extraJumpsValue;
        }

        if (Input.GetButtonDown("Jump") && extraJumps > 0)
        {
            Jump(1);
            extraJumps--;

        }
        else if (Input.GetButtonDown("Jump") && extraJumps == 0 && isGrounded == true)
        {
            Jump(1);
        }




    }
    private void FixedUpdate()
    {
        rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
        //rb.AddForce(new Vector2(moveInput * speed, rb.velocity.y));

        Collider2D jumpattackCol = Physics2D.OverlapBox(jumpattack.position, jumpattackSize, 0f, 1<<9);

        if (jumpattackCol != null && jumpattackCol.CompareTag("Enemy"))
        {
            DoDamage(jumpattackCol);
        }

    }



    void Flip()
    {
        facingRight = !facingRight;
        Vector3 Scaler = transform.localScale;
        Scaler.x *= -1;
        transform.localScale = Scaler;
    }

    void Jump(float multiplier)
    {
        SoundManager.PlaySounds(JumpSound);
        rb.velocity = Vector2.up * defaultJumpForce * multiplier;

    }

    void recieveUIRequest()
    {
        UISlider jumpForceSlider = new UISlider("PLAYER JUMP FORCE", minJumpForce, defaultJumpForce, maxJumpForce);

        UISlider speedSlider = new UISlider("PLAYER SPEED", minSpeed, speed, maxSpeed);

        UISlider[] playerSettings = new UISlider[2];

        playerSettings[0] = jumpForceSlider;
        playerSettings[1] = speedSlider;

        ObjectReciever.Instance.recieveObjectValues(playerSettings);
    }

    void recieveUpdatedValuesFromUI(float[] newValues)
    {
        defaultJumpForce = newValues[0];
        speed = newValues[1];
    }

    public void Respawn()
    {
        
        //death animation
        GameObject clone = Instantiate(deathParticle, transform);
        clone.transform.parent = null;
        Destroy(clone, 5f);

        //sound
        SoundManager.PlaySounds(deathSound);
        
        //respawn player on start position
        transform.position = startPosition;
        //rb.bodyType = RigidbodyType2D.Kinematic;

        rb.velocity = new Vector2(0, 0);
    }

    void MovingPlatform()
    {
        if (hitObject.tag == "MovingPlatform")
        {
            this.transform.parent = hitObject.transform;
        }

        else
        {
            this.transform.parent = null;
        }
    }

    void DoDamage(Collider2D enemy)
    {
        IDamageable entityInterface = (IDamageable)enemy.GetComponent(typeof(IDamageable));
        if (entityInterface != null)
        {
            entityInterface.GetDamage(entity.dealDamage);
        }
        Jump(0.5f);
    }


}
