using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif

// Basic touch/mouse movement controller suitable for top-down 2D or 3D overworld
// Attach to the player GameObject. Works with or without Rigidbody/Rigidbody2D.
public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
{
    public float moveSpeed = 5f;
    public float stopDistance = 0.1f;

    // If true and a Rigidbody/Rigidbody2D is present, movement will use physics MovePosition.
    public bool useRigidbody = true;

    Vector3 targetPosition;
    bool hasTarget = false;

    Rigidbody rb3d;
    Rigidbody2D rb2d;

    void Awake()
    {
        rb3d = GetComponent<Rigidbody>();
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Start()
    {
        // Initialize target to current position so object doesn't snap
        targetPosition = transform.position;
        hasTarget = false;
    }

    void OnEnable()
    {
        InputManager.Instance?.SetDefaultConsumer(this);
    }

    // Remove Update and HandleInput

    public void OnTouchPress(Vector2 worldPosition)
    {
        Debug.Log($"PlayerTouchController.OnTouchPress received worldPosition: {worldPosition}");
        SetTargetPosition(worldPosition);
    }

    public void OnTouchPosition(Vector2 screenPosition)
    {
        Debug.Log($"PlayerTouchController.OnTouchPosition called with screenPosition: {screenPosition}");
        // Optionally handle drag/move here
    }

    void SetTargetPosition(Vector2 worldPosition)
    {
        Debug.Log($"PlayerTouchController.SetTargetPosition: worldPosition={worldPosition}");
        targetPosition = new Vector3(worldPosition.x, worldPosition.y, transform.position.z);
        hasTarget = true;
    }

    void FixedUpdate()
    {
        if (hasTarget)
        {
            MoveTowardsTarget();
        }
    }

    void MoveTowardsTarget()
    {
        // Keep original y (or z for 2D) depending on scene setup. We assume the player moves on the plane defined by its current transform.
        Vector3 current = transform.position;

        // Create a target that preserves the movement plane (so we don't change vertical axis unexpectedly)
        Vector3 planarTarget = targetPosition;

        // If the camera is orthographic top-down (y is up), preserve y
        // Heuristic: if camera forward is (0,-1,0) then y is up and we should preserve y
        Camera cam = Camera.main;
        if (cam != null && Vector3.Dot(cam.transform.forward, Vector3.down) > 0.5f)
        {
            planarTarget.y = current.y;
        }
        else
        {
            // Otherwise assume z is depth for 2D setups and preserve z
            planarTarget.z = current.z;
        }

        float step = moveSpeed * Time.deltaTime;
        Vector3 next = Vector3.MoveTowards(current, planarTarget, step);

        // If using Rigidbody, move via physics when present
        if (useRigidbody && rb2d != null)
        {
            rb2d.MovePosition(new Vector2(next.x, next.y));
            transform.position = new Vector3(next.x, next.y, transform.position.z); // ensure transform matches
        }
        else if (useRigidbody && rb3d != null)
        {
            rb3d.MovePosition(next);
        }
        else
        {
            transform.position = next;
        }

        if (Vector3.Distance(transform.position, planarTarget) <= stopDistance)
        {
            hasTarget = false;
        }
    }
}
