using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

/// <summary>
/// GAME 1303 Tier 3 — A runaway hot air balloon. Replaces PlayerController2D for Hot Air.
///
/// Feel: the balloon always sinks slowly. Hold Jump to fire the burner — it pushes you up
/// and burns fuel. Left/Right gives a weak nudge (a balloon isn't a plane). Wind zones
/// shove you around. With no fuel you just drift down.
///
/// SETUP
///  1. Balloon: Sprite + Rigidbody2D (Gravity Scale 0.3, Linear Damping 1, Angular
///     Damping 2, DON'T freeze rotation — a little tilt looks great) + Collider2D +
///     Health + FuelSystem + this script + PlayerInput (Send Messages). Tag "Player".
///  2. Optional Basket child with the collider offset low, so the balloon tilts realistically.
///  3. Burner Force vs gravity: with Gravity Scale 0.3 and Rigidbody mass 1, a Burner
///     Force of 8 gives a nice slow climb. Tune Sink Speed Max so it never plummets.
///  4. Pair with GrapplingHook (Aim = Mouse) on the same object.
///  5. Burner Particles: drag a Particle System; it plays while burning.
///
/// Checkpoints, Health, DamageOnContact, RespawnManager all work unchanged — the
/// RespawnManager looks for PlayerController2D but tolerates its absence.
/// </summary>
[RequireComponent(typeof(Rigidbody2D))]
public class BalloonController : MonoBehaviour
{
    [Header("Burner")]
    public float burnerForce = 8f;
    public float fuelPerSecond = 10f;
    public float maxRiseSpeed = 5f;

    [Header("Drift")]
    public float horizontalForce = 3f;
    public float maxHorizontalSpeed = 4f;
    public float maxSinkSpeed = 3f;
    [Tooltip("Torque from horizontal input so the balloon leans into the move.")]
    public float leanTorque = 0.5f;
    [Tooltip("Spring that rights the balloon back to upright.")]
    public float uprightSpring = 2f;

    [Header("References")]
    public FuelSystem fuel;
    public ParticleSystem burnerParticles;

    [Header("Events")]
    public UnityEvent OnBurnerStarted;
    public UnityEvent OnBurnerStopped;

    public bool IsBurning { get; private set; }
    public bool InputEnabled { get; set; } = true;

    private Rigidbody2D rb;
    private Vector2 moveInput;
    private bool burnerHeld;

    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        if (fuel == null) fuel = GetComponent<FuelSystem>();
    }

    void OnMove(InputValue v) { moveInput = v.Get<Vector2>(); }
    void OnJump(InputValue v) { burnerHeld = v.isPressed; }

    void FixedUpdate()
    {
        bool canBurn = InputEnabled && burnerHeld && (fuel == null || !fuel.IsEmpty);

        // Burner
        if (canBurn)
        {
            if (fuel != null) fuel.Consume(fuelPerSecond * Time.fixedDeltaTime);
            if (rb.linearVelocity.y < maxRiseSpeed) rb.AddForce(Vector2.up * burnerForce);
        }
        SetBurning(canBurn);

        // Horizontal nudge
        if (InputEnabled && Mathf.Abs(moveInput.x) > 0.1f && Mathf.Abs(rb.linearVelocity.x) < maxHorizontalSpeed)
            rb.AddForce(Vector2.right * moveInput.x * horizontalForce);

        // Clamp sink speed
        if (rb.linearVelocity.y < -maxSinkSpeed)
            rb.linearVelocity = new Vector2(rb.linearVelocity.x, -maxSinkSpeed);

        // Lean + self-righting
        if (rb.freezeRotation == false)
        {
            rb.AddTorque(-moveInput.x * leanTorque);
            float angle = Mathf.DeltaAngle(rb.rotation, 0f);
            rb.AddTorque(angle * uprightSpring * Time.fixedDeltaTime);
        }
    }

    void SetBurning(bool on)
    {
        if (on == IsBurning) return;
        IsBurning = on;
        if (burnerParticles != null) { if (on) burnerParticles.Play(); else burnerParticles.Stop(); }
        if (on) OnBurnerStarted?.Invoke(); else OnBurnerStopped?.Invoke();
    }

    /// <summary>RespawnManager-friendly reset.</summary>
    public void ResetMotion()
    {
        rb.linearVelocity = Vector2.zero;
        rb.angularVelocity = 0f;
        rb.rotation = 0f;
    }
}