using TMPro;
using Unity.Cinemachine;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed;
    public float moveSpeedMultiplier;

    public LayerMask whatIsGround;
    public bool grounded;
    public Collider groundedCollider;
    public float airMultiplier;
    public bool airCollided;
    public bool groundCollided;

    public float maxSlopeAngle;
    private RaycastHit slopeHit;
    private bool exitingSlope;

    public Transform orientation;
    public Transform cameraor;

    public GameObject cinemachineCam;

    float horizontalInput;
    float verticalInput;

    public GameObject sword;
    public Transform swordSpawnPoint;
    public Transform swordSpawnPoint2;
    public Transform swordSpawnPoint3;
    public int lastSwing;
    public float timeSinceLastSwing;
    public bool holdSwing;
    public float holdSwingTimer;

    public float dashDistanceTimer, dashDistance, dashDuration;
    public Collider myCollider;
    public LayerMask excludeEnemy;

    public float HP = 10;

    public int inventorySlot = 1;

    public float energy = 100;
    public float swungTimer;
    public bool swung;
    public Slider energySlider;
    public GameObject energyObj;
    float energyObjTimer;
    public GameObject energyFill;

    Vector3 moveDirection;

    Rigidbody rb;

    public PhysicsMaterial walkingPhysics;
    public PhysicsMaterial standingPhysics;
    public PhysicsMaterial airColliding;

    public GameObject particle1;
    public GameObject particle2;
    public VolumeProfile volumeProfile;

    public RectTransform healthUI;
    bool jumped;
    bool jumping;

    public GameObject uiController;

    void Start()
    {
        cinemachineCam = GameObject.Find("CinemachineCamera");
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true;

    }

    void Update()
    {
        MyInput();
        SpeedControl();


        if (energy == 100)
        {
            energyObjTimer += Time.deltaTime;
            if (energyObjTimer > .4)
            {
                energyObj.SetActive(false);
            }

        }
        else
        {
            energyObjTimer = 0;
            energyObj.SetActive(true);
        }
    }
    void FixedUpdate()
    {
        MovePlayer();
    }
    private void MyInput()
    {
        
        if (Input.GetKeyDown(KeyCode.Alpha7))
        {
            HP -= 1;
        }
        if (Input.GetKeyDown(KeyCode.Alpha8))
        {
            HP -= .5f;
        }
        if (Input.GetKey(KeyCode.Alpha9))
        {
            HP -= Time.deltaTime;
        }
        if (Input.GetKeyDown(KeyCode.Alpha6))
        {
            HP = 10;
        }



        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            inventorySlot = 1;
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            inventorySlot = 2;
        }
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            inventorySlot = 3;
        }
        if (inventorySlot > 3)
            inventorySlot = 3;
        if (inventorySlot < 1)
            inventorySlot = 1;

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (Time.timeScale == 1)
            {
                uiController.GetComponent<PauseMenuControls>().mainCanvas.enabled = false;
                uiController.GetComponent<PauseMenuControls>().pauseCanvas.enabled = true;
                Time.timeScale = 0;
                Cursor.lockState = CursorLockMode.None;
                Cursor.visible = true;
            }
            else
            {
                uiController.GetComponent<PauseMenuControls>().mainCanvas.enabled = true;
                uiController.GetComponent<PauseMenuControls>().pauseCanvas.enabled = false;
                uiController.GetComponent<PauseMenuControls>().settingsCanvas.enabled = false;
                Time.timeScale = 1;
                Cursor.lockState = CursorLockMode.Locked;
                Cursor.visible = false;
            }

        }

        horizontalInput = Input.GetAxisRaw("Horizontal");
        verticalInput = Input.GetAxisRaw("Vertical");
        if (horizontalInput == 0 && verticalInput == 0 && grounded && !Input.GetKeyDown(KeyCode.Space))
        {
            rb.linearDamping = 7;
            
            GetComponent<CapsuleCollider>().material = standingPhysics;
        }
        else if (horizontalInput != 0 || verticalInput != 0 || !grounded || Input.GetKeyDown(KeyCode.Space))
        {
            rb.linearDamping = 0;
            
            GetComponent<CapsuleCollider>().material = walkingPhysics;
        }
        if (Input.GetKeyDown(KeyCode.Space) && grounded)
        {
            rb.linearDamping = 0;

            GetComponent<CapsuleCollider>().material = walkingPhysics;
            jumped = true;
            jumping = true;
        }
        
        if (jumped)
        {
            rb.linearDamping = 0;

            GetComponent<CapsuleCollider>().material = walkingPhysics;
            if (jumping)
            {
                rb.AddForce(Vector3.up * 6, ForceMode.Impulse);
                jumping = false;
            }
        }
        if (airCollided && !grounded)
        {
            rb.linearDamping = 0;
            GetComponent<CapsuleCollider>().material = airColliding;
            //rb.AddForce(Vector3.down * 1, ForceMode.Force);
            Debug.Log("ng, hs");

        }



        if (Time.timeScale == 1)
        {
            timeSinceLastSwing += Time.deltaTime;
            if (timeSinceLastSwing > .5f)
                lastSwing = 0;

            holdSwingTimer += Time.deltaTime;
            if (holdSwing && holdSwingTimer > .15f)
                holdSwing = false;
            else if (holdSwing && GameObject.FindGameObjectsWithTag("Sword").Length < 1)
            {
                holdSwing = false;
                if (energy > 7)
                    SwingSword();
            }
            if (!holdSwing)
                holdSwingTimer = 0;

            if (swung)
            {
                swungTimer += Time.deltaTime;
            }
            if (swungTimer > 1f)
                swung = false;
            if (!swung)
            {
                swungTimer = 0;
                energy += 70 * Time.deltaTime;

            }
            if (energy < 0)
                energy = 0;
            if (energy > 100)
                energy = 100;

            energySlider.value = energy;

            healthUI.sizeDelta = new Vector2((Mathf.Ceil(HP)-1) + (9 * HP), healthUI.sizeDelta.y);

            if (inventorySlot == 1)
            {
                if (Input.GetMouseButtonDown(0))
                {
                    if (GameObject.FindGameObjectsWithTag("Sword").Length < 1)
                    {
                        if (energy > 7)
                            SwingSword();
                    }
                    else
                    {
                        swung = true;
                        swungTimer = 0;
                        holdSwingTimer = 0;
                        holdSwing = true;
                    }
                }
                if (Input.GetMouseButton(0))
                {
                    swung = true;
                    swungTimer = 0;
                    timeSinceLastSwing = 0;

                    energy -= 20 * Time.deltaTime;
                    dashDistanceTimer += Time.deltaTime;
                    if (dashDistanceTimer > 1)
                        energyFill.GetComponent<Image>().color = Color.deepPink;
                    if (energy <= 0)
                    {
                        if (dashDistanceTimer > 1)
                        {
                            dashDistance = Mathf.Floor(dashDistanceTimer * 8);
                            dashDuration = 15;
                        }
                        dashDistanceTimer = 0;
                    }
                }
                //if (!Input.GetMouseButton(0))
                //energyFill.GetComponent<Image>().color = new Color(196, 3, 0, 255);
                if (Input.GetMouseButtonUp(0))
                {
                    energyFill.GetComponent<Image>().color = Color.darkRed;
                    if (dashDistanceTimer > 1)
                    {
                        dashDistance = Mathf.Floor(dashDistanceTimer * 8);
                        dashDuration = 15;
                    }
                    dashDistanceTimer = 0;
                }
            }

            if (inventorySlot == 2)
            {

            }

            if (inventorySlot == 3)
            {

            }
        }
    }
    private void LateUpdate()
    {
        
    }
    private void SwingSword()
    {
        swung = true;
        swungTimer = 0;
        energy -= 7;
        if (lastSwing == 0 || lastSwing == 3)
        {
            GameObject newSword = Instantiate(sword, swordSpawnPoint);
            lastSwing = 1;
            timeSinceLastSwing = 0;
        }
        else if (lastSwing == 1)
        {
            GameObject newSword = Instantiate(sword, swordSpawnPoint2);
            lastSwing = 2;
            timeSinceLastSwing = 0;
        }
        else if (lastSwing == 2)
        {
            GameObject newSword = Instantiate(sword, swordSpawnPoint3);
            lastSwing = 3;
            timeSinceLastSwing = 0;
        }
    }

    private void MovePlayer()
    {
        moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;


        if (grounded)
            rb.AddForce(moveDirection.normalized * moveSpeed * moveSpeedMultiplier * 3, ForceMode.Force);

        else if (!grounded)
            rb.AddForce(moveDirection.normalized * moveSpeed * moveSpeedMultiplier * airMultiplier, ForceMode.Force);

        

        if (rb.linearVelocity.y < -1)
        {
            rb.AddForce(transform.up * -5, ForceMode.Force);
        }

        if (dashDuration > 0)
        {
            SwordDash();

            dashDuration--;
        }
        if (dashDuration == 1)
        {
            rb.linearVelocity = Vector3.zero;

            dashDuration--;
        }
    }
    private void SwordDash()
    {
        myCollider.excludeLayers = excludeEnemy;

        rb.AddForce(Camera.main.transform.forward * dashDistance, ForceMode.Impulse);
        swung = true;
        swungTimer = 0;
        timeSinceLastSwing = 0;
    }
    private void SpeedControl()
    {

        {
            Vector3 flatVel = new Vector3(rb.linearVelocity.x, 0f, rb.linearVelocity.z);

            if (flatVel.magnitude > moveSpeed)
            {
                Vector3 limitedVel = flatVel.normalized * moveSpeed;
                rb.linearVelocity = new Vector3(limitedVel.x, rb.linearVelocity.y, limitedVel.z);
            }
        }

    }
    private bool OnSlope()
    {

        if (Physics.Raycast(transform.position, Vector3.down, out slopeHit, 2 * 0.5f + 0.3f))
        {
            float angle = Vector3.Angle(Vector3.up, slopeHit.normal);
            return angle < maxSlopeAngle && angle != 0;
        }

        return false;
    }
    private Vector3 GetSlopeDirection()
    {
        return Vector3.ProjectOnPlane(moveDirection, slopeHit.normal).normalized;
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Enemy")
        {
            HP--;
        }
        if (!other.isTrigger/* && other.gameObject.tag == "Ground"*/)
        {

            grounded = true;
            if (jumped)
                jumped = false;
        }
    }
    private void OnTriggerStay(Collider other)
    {
        if (!other.isTrigger/* && other.gameObject.tag == "Ground"*/)
        {

            grounded = true;
        }
    }
    private void OnTriggerExit(Collider other)
    {
        if (!other.isTrigger/* && other.gameObject.tag == "Ground"*/)
        {
            grounded = false;
        }
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (!grounded)
        {
            
        }
    }
    private void OnCollisionStay(Collision collision)
    {
        if (!grounded)
        {
            airCollided = true;
            
        }
    }
    private void OnCollisionExit(Collision collision)
    {
        if (!grounded)
        {
            airCollided = false;
            
        }
    }
}
