using System.Collections;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// GAME 1303 Tier 4 — A hazard that switches on and off: flame jets, electric arcs,
/// laser bars, geysers. Cutthroat Course (fire), Zap Attack (arcs).
///
/// SETUP
///  1. Object with Collider2D (Is Trigger) + DamageOnContact (Damage or Instant Kill;
///     set Repeat Interval ~0.5 for a burning feel) + this script.
///  2. Visuals: drag in a SpriteRenderer, a ParticleSystem, and/or a Light2D object — they're
///     enabled while the hazard is on and disabled while off. Warning Renderer (optional):
///     a faint "about to fire" sprite shown during Warning Time.
///  3. On Time / Off Time / Start Delay. Start On for hazards that begin active.
///  4. Always On = ignores the timer (a plain fire pit / acid pool). You then only get the
///     visual bookkeeping, which is still handy.
///
/// For a pure "acid pool that kills on touch" you don't need this at all — just a trigger
/// + DamageOnContact with Instant Kill. Use CyclingHazard when timing is the puzzle.
/// </summary>
[RequireComponent(typeof(DamageOnContact))]
public class CyclingHazard : MonoBehaviour
{
    public bool alwaysOn = false;
    public bool startOn = false;
    public float startDelay = 0f;
    public float onTime = 1f;
    public float offTime = 1.5f;
    public float warningTime = 0.3f;

    [Header("Visuals (optional)")]
    public SpriteRenderer sprite;
    public ParticleSystem particles;
    public GameObject lightObject;
    public SpriteRenderer warningRenderer;

    [Header("Audio")]
    public string onSfx = "";
    public AudioSource loopWhileOn;

    public UnityEvent OnActivated;
    public UnityEvent OnDeactivated;

    public bool IsOn { get; private set; }

    protected DamageOnContact damage;

    protected virtual void Awake()
    {
        damage = GetComponent<DamageOnContact>();
    }

    protected virtual void Start()
    {
        if (warningRenderer) warningRenderer.enabled = false;
        if (alwaysOn) { SetOn(true); return; }
        SetOn(startOn);
        StartCoroutine(Loop());
    }

    IEnumerator Loop()
    {
        yield return new WaitForSeconds(startDelay);
        while (true)
        {
            if (IsOn)
            {
                yield return new WaitForSeconds(onTime);
                SetOn(false);
            }
            else
            {
                yield return new WaitForSeconds(Mathf.Max(0f, offTime - warningTime));
                if (warningRenderer) warningRenderer.enabled = true;
                yield return new WaitForSeconds(warningTime);
                if (warningRenderer) warningRenderer.enabled = false;
                SetOn(true);
            }
        }
    }

    public virtual void SetOn(bool on)
    {
        IsOn = on;
        if (damage) damage.enabled = on;
        if (sprite) sprite.enabled = on;
        if (lightObject) lightObject.SetActive(on);
        if (particles) { if (on) particles.Play(); else particles.Stop(); }
        if (loopWhileOn) { if (on && !loopWhileOn.isPlaying) loopWhileOn.Play(); else if (!on) loopWhileOn.Stop(); }
        if (on)
        {
            if (!string.IsNullOrEmpty(onSfx)) AudioManager.Instance?.PlaySFX(onSfx);
            OnActivated?.Invoke();
        }
        else OnDeactivated?.Invoke();
    }
}