using UnityEngine;

/// <summary>
/// GAME 1303 Tier 1 — Platform that travels between waypoints and carries the player.
///
/// SETUP
///  1. Platform GameObject: SpriteRenderer, BoxCollider2D, Rigidbody2D (Body Type = Kinematic),
///     and this script.
///  2. Create empty child objects as waypoints, then UN-parent them (drag out to scene root)
///     so they don't move with the platform. Drag them into the Waypoints list in order.
///  3. Loop = go A→B→C→A. Ping-Pong = A→B→C→B→A.
///  4. The player is carried by being parented while standing on top. If your player
///     is a prefab and you get scale weirdness, make sure the platform's scale is (1,1,1).
///
/// Also usable for Cutthroat Course's Crusher (2 waypoints, fast) or drifting hazards.
/// </summary>
[RequireComponent(typeof(Rigidbody2D))]
public class MovingPlatform : MonoBehaviour
{
    public enum Mode { Loop, PingPong }

    public Transform[] waypoints;
    public float speed = 2f;
    public Mode mode = Mode.PingPong;
    [Tooltip("Pause at each waypoint.")]
    public float waitAtWaypoint = 0.3f;
    [Tooltip("Tag of objects that should ride the platform.")]
    public string riderTag = "Player";

    private Rigidbody2D rb;
    private int index;
    private int dir = 1;
    private float waitTimer;

    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        rb.bodyType = RigidbodyType2D.Kinematic;
        if (waypoints != null && waypoints.Length > 0) transform.position = waypoints[0].position;
    }

    void FixedUpdate()
    {
        if (waypoints == null || waypoints.Length < 2) return;

        if (waitTimer > 0f) { waitTimer -= Time.fixedDeltaTime; return; }

        Vector2 target = waypoints[index].position;
        Vector2 next = Vector2.MoveTowards(rb.position, target, speed * Time.fixedDeltaTime);
        rb.MovePosition(next);

        if (Vector2.Distance(next, target) < 0.01f)
        {
            waitTimer = waitAtWaypoint;
            Advance();
        }
    }

    void Advance()
    {
        if (mode == Mode.Loop)
        {
            index = (index + 1) % waypoints.Length;
        }
        else
        {
            if (index + dir >= waypoints.Length || index + dir < 0) dir = -dir;
            index += dir;
        }
    }

    // Carry the rider: parent them while they stand on us
    void OnCollisionEnter2D(Collision2D col)
    {
        if (!col.collider.CompareTag(riderTag)) return;
        // Only if they're on top (contact normal points down onto us)
        foreach (var contact in col.contacts)
            if (contact.normal.y < -0.5f) { col.transform.SetParent(transform); break; }
    }

    void OnCollisionExit2D(Collision2D col)
    {
        if (col.collider.CompareTag(riderTag) && col.transform.parent == transform)
            col.transform.SetParent(null);
    }

    void OnDrawGizmos()
    {
        if (waypoints == null) return;
        Gizmos.color = Color.cyan;
        for (int i = 0; i < waypoints.Length; i++)
        {
            if (waypoints[i] == null) continue;
            Gizmos.DrawSphere(waypoints[i].position, 0.1f);
            if (i + 1 < waypoints.Length && waypoints[i + 1] != null)
                Gizmos.DrawLine(waypoints[i].position, waypoints[i + 1].position);
        }
    }
}