using UnityEngine;
using UnityEngine.InputSystem;

namespace InfiniteWorld
{
    public class SimplePlayerInputMover : MonoBehaviour
    {
        [SerializeField] private float moveSpeed = 5f;

        private InputAction moveAction;
        private Rigidbody2D rb;
        private Vector2 moveInput;

        private void Awake()
        {
            rb = GetComponent<Rigidbody2D>();
            if (rb == null)
            {
                rb = gameObject.AddComponent<Rigidbody2D>();
            }

            ConfigurePhysics();
            EnsureVisual();

            moveAction = new InputAction("Move", InputActionType.Value);
            moveAction.AddCompositeBinding("2DVector")
                .With("Up", "<Keyboard>/w")
                .With("Down", "<Keyboard>/s")
                .With("Left", "<Keyboard>/a")
                .With("Right", "<Keyboard>/d");
            moveAction.AddCompositeBinding("2DVector")
                .With("Up", "<Keyboard>/upArrow")
                .With("Down", "<Keyboard>/downArrow")
                .With("Left", "<Keyboard>/leftArrow")
                .With("Right", "<Keyboard>/rightArrow");
            moveAction.AddBinding("<Gamepad>/leftStick");
        }

        private void OnEnable()
        {
            moveAction?.Enable();
        }

        private void OnDisable()
        {
            moveAction?.Disable();
        }

        private void OnDestroy()
        {
            moveAction?.Dispose();
        }

        private void Update()
        {
            if (moveAction == null)
            {
                return;
            }

            moveInput = moveAction.ReadValue<Vector2>().normalized;
            if (moveInput.x != 0f)
            {
                Vector3 scale = transform.localScale;
                scale.x = Mathf.Abs(scale.x) * Mathf.Sign(moveInput.x);
                transform.localScale = scale;
            }
        }

        private void FixedUpdate()
        {
            if (rb == null)
            {
                return;
            }

            Vector2 target = rb.position + moveInput * (moveSpeed * Time.fixedDeltaTime);
            rb.MovePosition(target);
        }

        private void ConfigurePhysics()
        {
            rb.gravityScale = 0f;
            rb.freezeRotation = true;
            rb.interpolation = RigidbodyInterpolation2D.Interpolate;
            rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;

            CapsuleCollider2D collider = GetComponent<CapsuleCollider2D>();
            if (collider == null)
            {
                collider = gameObject.AddComponent<CapsuleCollider2D>();
            }
            collider.direction = CapsuleDirection2D.Vertical;
            collider.size = new Vector2(0.55f, 0.8f);
            collider.offset = new Vector2(0f, -0.05f);
        }

        private void EnsureVisual()
        {
            SpriteRenderer renderer = GetComponent<SpriteRenderer>();
            if (renderer == null)
            {
                renderer = gameObject.AddComponent<SpriteRenderer>();
            }
            renderer.sprite = ProceduralWorldArt.CreatePlayerSprite();
            renderer.sortingOrder = 10;
        }
    }
}
