using UnityEngine;

/// <summary>
/// GAME 1303 Tier 2 — Walks back and forth. Turns at walls, ledges, or waypoints.
///
/// SETUP
///  1. Enemy root: Sprite + Rigidbody2D (Freeze Rotation Z) + Collider2D + Health +
///     this script. Tag "Enemy". Add a Hurtbox child (Team = Enemy) so the player can hit it,
///     and either a Hitbox child (always on, Target Team = Player, Repeat Delay 1) or a
///     DamageOnContact so it hurts the player on touch.
///  2. Turn mode:
///       Sensors   – flips when the Wall Check hits Ground Layer or the Ledge Check finds
///                   no ground ahead. Create two empty children: "WallCheck" (in front, at
///                   knee height) and "LedgeCheck" (in front, below the feet).
///       Waypoints – walks between two Transforms (drag them out of the enemy so they
///                   don't move with it).
///  3. Optional: drag in a PlayerAnimatorBridge on the same object and it drives Speed.
///
/// EnemyChase can sit on the same object and take over when the player is near;
/// it pauses this script while chasing.
/// </summary>
[RequireComponent(typeof(Rigidbody2D))]
public class EnemyPatrol : MonoBehaviour
{
    public enum TurnMode { Sensors, Waypoints }

    public float speed = 2f;
    public TurnMode turnMode = TurnMode.Sensors;
    [Tooltip("Pause at each turn.")]
    public float pauseAtTurn = 0.3f;
    [Tooltip("Sprite faces right by default? Untick if your art faces left.")]
    public bool artFacesRight = true;

    [Header("Sensors mode")]
    public Transform wallCheck;
    public Transform ledgeCheck;
    public float checkDistance = 0.15f;
    public LayerMask groundLayer;

    [Header("Waypoints mode")]
    public Transform pointA;
    public Transform pointB;

    public bool FacingRight { get; private set; } = true;
    /// <summary>EnemyChase sets this false while chasing.</summary>
    public bool Active { get; set; } = true;

    private Rigidbody2D rb;
    private Knockback knockback;
    private PlayerAnimatorBridge animBridge;
    private Transform currentTarget;
    private float pauseTimer;

    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        knockback = GetComponent<Knockback>();
        animBridge = GetComponent<PlayerAnimatorBridge>();
        currentTarget = pointB;
        FacingRight = artFacesRight ? transform.localScale.x > 0 : transform.localScale.x < 0;
    }

    void FixedUpdate()
    {
        if (!Active || (knockback != null && knockback.IsStunned))
        {
            animBridge?.SetSpeed(0f);
            return;
        }

        if (pauseTimer > 0f)
        {
            pauseTimer -= Time.fixedDeltaTime;
            rb.linearVelocity = new Vector2(0f, rb.linearVelocity.y);
            animBridge?.SetSpeed(0f);
            return;
        }

        if (turnMode == TurnMode.Sensors) SensorPatrol();
        else WaypointPatrol();

        animBridge?.SetSpeed(rb.linearVelocity.x);
    }

    void SensorPatrol()
    {
        float dir = FacingRight ? 1f : -1f;
        bool wallAhead = wallCheck != null &&
            Physics2D.Raycast(wallCheck.position, Vector2.right * dir, checkDistance, groundLayer);
        bool groundAhead = ledgeCheck == null ||
            Physics2D.Raycast(ledgeCheck.position, Vector2.down, checkDistance * 3f, groundLayer);

        if (wallAhead || !groundAhead) { Flip(); return; }

        rb.linearVelocity = new Vector2(dir * speed, rb.linearVelocity.y);
    }

    void WaypointPatrol()
    {
        if (pointA == null || pointB == null) return;
        float dx = currentTarget.position.x - transform.position.x;
        if (Mathf.Abs(dx) < 0.1f)
        {
            currentTarget = currentTarget == pointA ? pointB : pointA;
            pauseTimer = pauseAtTurn;
            return;
        }
        float dir = Mathf.Sign(dx);
        if ((dir > 0) != FacingRight) Flip();
        rb.linearVelocity = new Vector2(dir * speed, rb.linearVelocity.y);
    }

    public void Flip()
    {
        FacingRight = !FacingRight;
        Vector3 s = transform.localScale;
        s.x *= -1f;
        transform.localScale = s;
        pauseTimer = pauseAtTurn;
    }

    /// <summary>Face a world position (EnemyChase uses this).</summary>
    public void FaceToward(float worldX)
    {
        bool shouldFaceRight = worldX > transform.position.x;
        if (shouldFaceRight != FacingRight) { Flip(); pauseTimer = 0f; }
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        float dir = Application.isPlaying ? (FacingRight ? 1 : -1) : 1;
        if (wallCheck) Gizmos.DrawLine(wallCheck.position, wallCheck.position + Vector3.right * dir * checkDistance);
        if (ledgeCheck) Gizmos.DrawLine(ledgeCheck.position, ledgeCheck.position + Vector3.down * checkDistance * 3f);
        if (pointA && pointB) { Gizmos.color = Color.yellow; Gizmos.DrawLine(pointA.position, pointB.position); }
    }
}