using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BayatGames.SaveGameFree;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;

public class PlayerController : MonoBehaviour
{
    // Can be used to block the movement while the menu is open...:
    public bool MovementAllowed = true;

    [SerializeField] Transform playerCamera = null;
    public float mouseSensitivity;
    private float crawlspeed = 0.4f;
    private float crouchspeed = 0.4f;
    private float walkspeed = 1.3f;
    private float runspeed = 2.8f;
    private float gravity = -13.0f;
    [Range(0.0f, 0.5f)] float moveSmoothTime = 0.13f;
    [Range(0.0f, 0.5f)] float mouseSmoothTime = 0.01f;

    bool lockCursor = true;
    float cameraPitch = 0f;
    float velocityY = 0f;
    CharacterController controller = null;
    Vector2 currentDir = Vector2.zero;
    Vector2 currentDirVelocity = Vector2.zero;
    Vector2 currentMouseDelta = Vector2.zero;
    Vector2 currentMouseDeltaVelocity = Vector2.zero;
    private Animator animcontroller;


    autocrawl_twoDimensionalAnimationStateController isInATriggerSCRIPT;
    void Start()
    {
        isInATriggerSCRIPT = GetComponent<autocrawl_twoDimensionalAnimationStateController>();

        animcontroller = GetComponent<Animator>();
        controller = GetComponent<CharacterController>();
        if (lockCursor)
        {
            Cursor.lockState = CursorLockMode.Locked;
            Cursor.visible = false;
        }
    }
    ////////// New Input System Anfang //////////////////
    private PlayerActionControls _controls2;
    void Awake()
    {
        _controls2 = new PlayerActionControls();

        mouseSensitivity = SaveGame.Load<float>("MeineMausEmpfindlichkeit");
        // Sicherheits Mindestbeschleunigung (Damit das Bild nicht stehen bleibt und man weis das es and der Mausgeschwidigkeit liegt!!!
        if (mouseSensitivity < 0.02f)
        {
            mouseSensitivity = 0.02f;
        }
        mouseSensitivity = mouseSensitivity * 5f; // "5" Ist der Faktor mit dem sich der Slider multipliziert fuer die endgueltige Mausgeschwidigkeit...
        //Debug.Log("mouseSensitivity = " + mouseSensitivity);
    }

    private void OnEnable()
    {
        _controls2.Enable();
    }
    private void OnDisable()
    {
        _controls2.Disable();
    }
    ////////// New Input System Ende //////////////////
    // W,A,S,D Steuerung
    void UpdateMovement()
    {
        // Hollt den Vector2 hier rein:
        Vector2 movementInput = _controls2.Player.Movement.ReadValue<Vector2>();
        float xInput = movementInput.x;
        float yInput = movementInput.y;
        bool isCrouching = _controls2.Player.Movement_Crouch.ReadValue<float>() != 0;
        bool isSprinting = _controls2.Player.Movement_Run.ReadValue<float>() != 0;



        Vector2 targetDir = new Vector2(xInput, yInput);
        targetDir.Normalize();
        currentDir = Vector2.SmoothDamp(currentDir, targetDir, ref currentDirVelocity, moveSmoothTime);
        if (controller.isGrounded)
        {
            velocityY = 0.0f;
        }
        velocityY += gravity * Time.deltaTime;
        Vector3 velocity = (transform.forward * currentDir.y + transform.right * currentDir.x);

        //Debug.Log("Gerade Trozdem = X: " + xInput);
        //Debug.Log("Gerade Trozdem = Y: " + yInput);
        if (isInATriggerSCRIPT.isInATrigger) //Crawling
        {
            //Debug.Log(" UNDER THE BED!!");
            velocity *= crawlspeed;
        }
        else
        {
            // Animationszuweisung:
            if (isSprinting)
            {
                if (!isCrouching)
                {
                    // Geht sicher das es fuer diese Animationen keine Seitliche Bewegungen gibt!
                    if (yInput > 0.7f)
                    {
                        //Debug.Log("RunAktiv = X: " + xInput);
                        //Debug.Log("RunAktiv = Y: " + yInput);
                        velocity *= runspeed;
                    }
                }
            }
            else if (xInput != 0f || yInput != 0f) // Solange zumindest eine Bewegungsrichtung noch aktiv ist...
            {
                //Debug.Log("WalkAktiv = X: " + xInput);
                //Debug.Log("WalkAktiv = Y: " + yInput);
                velocity *= walkspeed;
            }

            if (isCrouching) // Wenn "STRG" gedrueckt, und keine bewegungsrichtung aktiv ist:
            {
                //Debug.Log("CrouchAktiv = X: " + xInput);
                //Debug.Log("CrouchAktiv = Y: " + yInput);
                velocity *= crouchspeed;
            }
        }

        

        velocity += Vector3.up * velocityY;
        controller.Move(velocity * Time.deltaTime);
    }

    // Maus Umschauen
    void UpdateMouseLook()
    {
        Vector2 targetMouseDelta = _controls2.Player.Camera_Movement.ReadValue<Vector2>();
        //Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")); //Old input system

        /*Vector2 A = _controls2.Player.Camera_Movement.ReadValue<Vector2>();
        Vector2 targetMouseDelta = new Vector2(A.x, A.y);*/

        currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, mouseSmoothTime);

        cameraPitch -= currentMouseDelta.y * mouseSensitivity;
        cameraPitch = Mathf.Clamp(cameraPitch, -60.0f, 80.0f); //"-60" = Zur Decke gucken // "80" = Nach unten

        playerCamera.localEulerAngles = Vector3.right * cameraPitch;

        transform.Rotate(Vector3.up * currentMouseDelta.x * mouseSensitivity);
    }

    void Update()
    {
        // if the player opens the menu for example, the player should no longer move:
        if (MovementAllowed)
        {
            UpdateMouseLook();
            UpdateMovement();
        }
    }
}