using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// GAME 1303 Tier 4 — A lever, button, or pressure plate that drives something else
/// (usually a Door). Anabasis, Apep's Trial, Zap Attack, Spark of Corruption.
///
/// SETUP
///  1. Sprite + Collider2D (Is Trigger) + this script.
///  2. Activation:
///       Touch        – flips when the player walks into it.
///       Stand        – ON while something stands on it, OFF when they leave
///                      (a pressure plate; a crate counts if Any Rigidbody is ticked).
///       Hit          – needs a Tier 2 attack. Add a Hurtbox child (Team Neutral) and a
///                      Health (1 HP, Destroy On Death off), then wire Health.OnDamaged
///                      -> PuzzleSwitch.Activate.
///  3. One Shot: once on, stays on.
///  4. Wire OnActivated -> Door.Open (or anything else). OnDeactivated for plates.
///  5. Sprites: On/Off sprites swap automatically if assigned.
///
/// Several switches into one door: put a SwitchGroup on the door's parent (below).
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class PuzzleSwitch : MonoBehaviour
{
    public enum Activation { Touch, Stand, Hit }

    public Activation activation = Activation.Touch;
    public bool oneShot = true;
    [Tooltip("Stand mode: crates and other rigidbodies can hold it down, not just the player.")]
    public bool anyRigidbody = false;

    [Header("Look")]
    public SpriteRenderer spriteRenderer;
    public Sprite offSprite;
    public Sprite onSprite;
    public string onSfx = "switch_on";
    public string offSfx = "";

    [Header("Events")]
    public UnityEvent OnActivated;
    public UnityEvent OnDeactivated;

    public bool IsOn { get; private set; }

    private int standingCount;

    void Reset() { GetComponent<Collider2D>().isTrigger = true; }

    void Awake()
    {
        if (spriteRenderer == null) spriteRenderer = GetComponent<SpriteRenderer>();
        Refresh();
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (!Accepts(other)) return;
        if (activation == Activation.Touch) Activate();
        else if (activation == Activation.Stand) { standingCount++; if (standingCount == 1) SetState(true); }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (activation != Activation.Stand || !Accepts(other)) return;
        standingCount = Mathf.Max(0, standingCount - 1);
        if (standingCount == 0 && !oneShot) SetState(false);
    }

    bool Accepts(Collider2D other)
    {
        if (other.CompareTag("Player")) return true;
        return anyRigidbody && other.attachedRigidbody != null;
    }

    /// <summary>Flip it on (or toggle if not one-shot). Wire attacks / Interactables here.</summary>
    public void Activate()
    {
        if (IsOn && oneShot) return;
        SetState(oneShot || !IsOn);
    }

    public void SetState(bool on)
    {
        if (on == IsOn) return;
        IsOn = on;
        Refresh();
        string sfx = on ? onSfx : offSfx;
        if (!string.IsNullOrEmpty(sfx)) AudioManager.Instance?.PlaySFX(sfx);
        if (on) OnActivated?.Invoke(); else OnDeactivated?.Invoke();
    }

    void Refresh()
    {
        if (spriteRenderer == null) return;
        Sprite s = IsOn ? onSprite : offSprite;
        if (s != null) spriteRenderer.sprite = s;
    }
}