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

public class PlayerController : MonoBehaviour
{
    public Rigidbody rb;
    public Transform head;
    public Transform groundAnchor;
    public Gun[] guns;

    public float groundRadius = 0.4f;
    public float jumpVelocity = 8;
    public float gravity = 30;
    public float drag = 0.9f;
    public float speed = 10;
    public float rotationSpeed = 10;

    public Gun currentGun => guns[gunIndex];

    public int gunIndex;

    private Vector3 moveAxis;
    private bool shouldJump;

    private void Start()
    {
        SetGun(gunIndex);
    }

    private void Update()
    {
        var moveInputAxis = Vector2.zero;
        moveInputAxis.x = GetAnyKey(KeyCode.RightArrow, KeyCode.D) ? 1 : GetAnyKey(KeyCode.LeftArrow, KeyCode.A) ? -1 : 0;
        moveInputAxis.y = GetAnyKey(KeyCode.UpArrow, KeyCode.W) ? 1 : GetAnyKey(KeyCode.DownArrow, KeyCode.S) ? -1 : 0;
        moveInputAxis = moveInputAxis.normalized;

        var rotation = head.rotation.eulerAngles.y;
        moveAxis = new Vector3(moveInputAxis.x, 0, moveInputAxis.y);
        moveAxis = Quaternion.Euler(0, rotation, 0) * moveAxis;

        var cameraInput = Vector2.zero;
        cameraInput.x = Input.GetAxis("Mouse X");
        cameraInput.y = Input.GetAxis("Mouse Y");

        var angles = head.eulerAngles;

        if (angles.x > 180)
            angles.x -= 360;
        if (angles.y > 180)
            angles.y -= 360;
        if (angles.z > 180)
            angles.z -= 360;

        angles.x += -cameraInput.y * rotationSpeed * Time.deltaTime;
        angles.y += cameraInput.x * rotationSpeed * Time.deltaTime;
        angles.z = 0;

        if (angles.x > 89) angles.x = 89;
        if (angles.x < -89) angles.x = -89;

        head.eulerAngles = angles;

        if (Input.mouseScrollDelta.y != 0)
        {
            gunIndex += Input.mouseScrollDelta.y > 0 ? 1 : -1;
            if (gunIndex >= guns.Length) gunIndex = 0;
            if (gunIndex < 0) gunIndex = guns.Length - 1;
            SetGun(gunIndex);
        }

        if (Input.GetKeyDown(KeyCode.Space) && IsGround())
        {
            shouldJump = true;
        }
    }

    public bool GetAnyKey(params KeyCode[] keyCode)
    {
        for (int i = 0; i < keyCode.Length; i++)
        {
            if (Input.GetKey(keyCode[i]))
                return true;
        }
        return false;
    }

    private void FixedUpdate()
    {
        rb.MovePosition(rb.position + moveAxis * speed * Time.fixedDeltaTime);

        rb.AddForce(Vector3.down * gravity * Time.fixedDeltaTime, ForceMode.Acceleration);

        var v = rb.velocity;
        v.x = v.x * drag * Time.fixedDeltaTime;
        v.z = v.z * drag * Time.fixedDeltaTime;

        if (shouldJump)
        {
            shouldJump = false;
            v.y = jumpVelocity;
        }

        rb.velocity = v;
    }

    public void SetGun(int index)
    {
        gunIndex = index;
        for (int i = 0; i < guns.Length; i++)
        {
            guns[i].gameObject.SetActive(i == index);
        }
    }

    public bool IsGround()
    {
        var cols = Physics.OverlapSphere(groundAnchor.position, groundRadius);
        if (cols.Any(e => e.GetComponent<Ground>() != null))
        {
            return true;
        }
        return false;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(groundAnchor.position, groundRadius);
    }
}
