namespace Marro.PacManUdon
{
    using System;
    using UdonSharp;
    using UnityEngine;
    using VRC.SDKBase;
    using VRC.Udon;
    using VRC.Udon.Common;

    public class PlayerInput : UdonSharpBehaviour
    {
        public bool active;
        private GameManager gameController;
        Vector2 inputHorizontal;
        Vector2 inputVertical;
        float horizontalValue;
        float verticalValue;
        bool horizontalPriority;
        VRCPlayerApi player;

        public void Initialize(GameManager gameController)
        {
            this.gameController = gameController;
            inputHorizontal = Vector2.zero;
            inputVertical = Vector2.zero;
            horizontalPriority = false;
            player = Networking.LocalPlayer;
        }

        public void Activate()
        {
            Debug.Log($"{gameObject} got activated, {player} was immobilized");
            active = true;
            player.SetWalkSpeed(0);
            player.SetRunSpeed(0);
            player.SetStrafeSpeed(0);

            gameController.JoystickGrabbed();
        }

        public void Deactivate()
        {
            Debug.Log($"{gameObject} got deactivated, {player} was released");
            player.SetWalkSpeed(2);
            player.SetRunSpeed(4);
            player.SetStrafeSpeed(2);
            active = false;

            gameController.JoystickReleased();
        }

        public override void InputJump(bool pressed, UdonInputEventArgs args)
        {
            if (!active)
            {
                return;
            }

            if (pressed)
            {
                Deactivate();
            }
        }

        public override void InputMoveHorizontal(float value, UdonInputEventArgs args)
        {
            if (!active)
            {
                return;
            }
            horizontalValue = Math.Abs(value);
            if (value < -0.5)
            {
                inputHorizontal = Vector2.left;
                if (horizontalValue >= verticalValue)
                {
                    // horizontalPriority = true;
                    SetPriority(true);
                }
            }
            else if (value > 0.5)
            {
                inputHorizontal = Vector2.right;
                if (horizontalValue >= verticalValue)
                {
                    // horizontalPriority = true;
                    SetPriority(true);
                }
            }
            else
            {
                inputHorizontal = Vector2.zero;
                // horizontalPriority = false;
                SetPriority(false);
            }

            // Debug.Log("Horizontal Input Event: " + value + " | Direction: " + direction + " | lastDirection: " + lastDirection + " | Left: " + left + " | Right: " + right);
        }

        public override void InputMoveVertical(float value, UdonInputEventArgs args)
        {
            if (!active)
            {
                return;
            }
            verticalValue = Math.Abs(value);
            if (value < -0.5)
            {
                inputVertical = Vector2.down;
                if (verticalValue >= horizontalValue)
                {
                    // horizontalPriority = false;
                    SetPriority(false);
                }
            }
            else if (value > 0.5)
            {
                inputVertical = Vector2.up;
                if (verticalValue >= horizontalValue)
                {
                    // horizontalPriority = false;
                    SetPriority(false);
                }
            }
            else
            {
                inputVertical = Vector2.zero;
                // horizontalPriority = true;
                SetPriority(true);
            }
            // Debug.Log("Vertical Input Event: " + value + " | Direction: " + direction + " | lastDirection : " + lastDirection);
        }

        private void SetPriority(bool horizontalPriority)
        {
            if (this.horizontalPriority != horizontalPriority)
            {
                player.PlayHapticEventInHand(VRC_Pickup.PickupHand.Left, 0.1f, 0.15f, 75);
                this.horizontalPriority = horizontalPriority;
            }
        }

        // public Vector2[] GetDirections() {
        //     return new Vector2[]{inputHorizontal, inputVertical};
        // }

        public Vector2 GetDirection()
        {
            if (horizontalPriority)
            {
                return inputHorizontal;
            }
            else
            {
                return inputVertical;
            }
        }

        public void OverrideDirection(Vector2 direction) // For recording the demo only, should not be used when shipped as it is very much a hack
        {
            inputHorizontal = new Vector2(direction.x, direction.y);
            horizontalPriority = true;
        }

        // public Vector2 GetRotatedDirection() {
        //     return RotateDirection(GetDirection(), rotation);
        // }

        // public Vector2 RotateDirection(Vector2 direction, int rotation) {
        //     rotation = rotation%4;
        //     // Debug.Log(direction + " " + rotation);
        //     switch(rotation) {
        //         default:
        //             return direction;
        //         case 1:
        //             return new Vector2(direction.y, -direction.x);
        //         case 2:
        //             return new Vector2(-direction.x, -direction.y);
        //         case 3:
        //             return new Vector2(-direction.y, direction.x);
        //     }
        // }

        // public override void InputLookHorizontal(float value, UdonInputEventArgs args)
        // {
        //     float rotation = player.GetRotation().eulerAngles.y;
        //     if(rotation > 45 && rotation <= 135) {
        //         // Debug.Log("Right");
        //         this.rotation = 1;
        //     } else if(rotation > 135 && rotation <= 225) {
        //         // Debug.Log("Backward");
        //         this.rotation = 2;
        //     } else if(rotation > 225 && rotation <= 315) {
        //         // Debug.Log("Left");
        //         this.rotation = 3;
        //     } else if(rotation > 315 || rotation <= 45) {
        //         // Debug.Log("Forward");
        //         this.rotation = 0;
        //     }
        // }
    }
}