/// SPΔWN[CAMPGAMES]™ 
/// SCRAPS (scripts-development) v2025 
/// License: CCBYNC4.0

// DEPLOY
using SPAWN.Debug;
using UnityEngine;

namespace SpawnCampGames.Character
{
    [RequireComponent(typeof(Rigidbody))]
    public class SpringSuspensionWithPlatform : MonoBehaviour
    {
        [Header("Suspension Settings")]
        public float rideHeight = 2f;
        public float springStrength = 50f;
        public float springDamping = 10f;
        public LayerMask groundMask = 1 << 0;

        [Header("Movement Settings")]
        public float moveSpeed = 5f;
        public float maxHorizontalSpeed = 10f;
        public float turnSpeed = 100f;
        public float horizontalDamp = 5f;

        private Rigidbody rb;

        // --- Platform support ---
        private Vector3 platformVelocity;           // velocity of current platform
        private MovingPlatform currentPlatform;    // reference to platform player is standing on

        void Start()
        {
            rb = GetComponent<Rigidbody>();
            rb.useGravity = false; // suspension handles gravity
        }

        void FixedUpdate()
        {
            ApplyRotation();
            ApplyMovement();
            ApplySuspension();
        }

        // --- Suspension (vertical movement) ---
        private void ApplySuspension()
        {
            Vector3 vel = rb.velocity;

            if (Physics.Raycast(transform.position, Vector3.down, out RaycastHit hit, rideHeight * 2f, groundMask))
            {
                float targetY = hit.point.y + rideHeight;

                // Add platform vertical motion if standing on a platform
                if (currentPlatform != null)
                    targetY += currentPlatform.GetVelocity().y * Time.fixedDeltaTime;

                float displacement = transform.position.y - targetY;
                float springAccel = (-springStrength * displacement) - (springDamping * vel.y);
                vel.y += springAccel * Time.fixedDeltaTime;
            }
            else
            {
                vel.y += Physics.gravity.y * Time.fixedDeltaTime;
            }

            rb.velocity = vel;
        }

        // --- Movement (horizontal) ---
        private void ApplyMovement()
        {
            float inputV = Input.GetAxis("Vertical");
            Vector3 forward = transform.forward;
            Vector3 vel = rb.velocity;

            Vector3 desiredVel = forward * inputV * moveSpeed;

            // Add horizontal platform velocity
            Vector3 totalVel = desiredVel + new Vector3(platformVelocity.x, 0f, platformVelocity.z);

            // Smooth horizontal movement
            float lerp = horizontalDamp * Time.fixedDeltaTime;
            vel.x = Mathf.Lerp(vel.x, totalVel.x, lerp);
            vel.z = Mathf.Lerp(vel.z, totalVel.z, lerp);

            // Clamp horizontal speed
            Vector3 flatVel = new Vector3(vel.x, 0, vel.z);
            if (flatVel.magnitude > maxHorizontalSpeed)
            {
                flatVel = flatVel.normalized * maxHorizontalSpeed;
                vel.x = flatVel.x;
                vel.z = flatVel.z;
            }

            rb.velocity = vel;
        }

        // --- Turning ---
        private void ApplyRotation()
        {
            float turnInput = Input.GetAxis("Horizontal");
            if (Mathf.Abs(turnInput) > 0.01f)
                transform.Rotate(Vector3.up, turnInput * turnSpeed * Time.fixedDeltaTime);
        }

        // --- Detect platform collisions ---
        void OnCollisionStay(Collision collision)
        {
            // Check if the player is standing on a platform
            if (collision.gameObject.TryGetComponent(out currentPlatform))
            {
                platformVelocity = currentPlatform.GetVelocity(); // grab platform velocity
            }
            else
            {
                platformVelocity = Vector3.zero;
                currentPlatform = null;
            }
        }
    }
}