using System.Collections;
using UnityEngine;

/// <summary>
/// GAME 1303 Tier 4 — Electricity. A CyclingHazard that also STUNS whoever it zaps, with
/// a random flicker so it reads as live current. Cutthroat Course ("jump too high and
/// you get shocked"), Zap Attack, The Magnet.
///
/// SETUP
///  - Same as CyclingHazard (trigger collider + DamageOnContact + visuals).
///  - For Nicholas's ceiling shock: stretch a wide thin trigger along the top of the
///    course, tick Always On, Damage 1 (or Instant Kill), Stun 0.5. Jump into it = zap.
///  - For arcs between two poles: Always On off, On/Off times, a lightning sprite or
///    particle as the visual, and a small warning sprite of sparks.
///  - Stun freezes PlayerController2D input for Stun Duration and lets the Hurt animation
///    show. Flicker randomly blinks the sprite while on.
///
/// Zap Attack's Blobby is MADE of electricity — give him a Health with a tag check, or
/// simply set the DamageOnContact Target Tag to something else so it's harmless to him.
/// </summary>
public class ElectricZone : CyclingHazard
{
    [Header("Electric")]
    public float stunDuration = 0.5f;
    public bool flicker = true;
    public float flickerRate = 20f;
    public string zapSfx = "zap";

    private Coroutine flickerRoutine;
    private readonly System.Collections.Generic.HashSet<PlayerController2D> stunned = new System.Collections.Generic.HashSet<PlayerController2D>();

    protected override void Awake()
    {
        base.Awake();
        // sensible defaults for electricity if the student hasn't touched them
        if (damage != null && damage.repeatInterval <= 0f) damage.repeatInterval = 0.4f;
    }

    public override void SetOn(bool on)
    {
        base.SetOn(on);
        if (flicker && sprite != null)
        {
            if (on && flickerRoutine == null) flickerRoutine = StartCoroutine(Flicker());
            else if (!on && flickerRoutine != null) { StopCoroutine(flickerRoutine); flickerRoutine = null; sprite.enabled = false; }
        }
    }

    IEnumerator Flicker()
    {
        while (true)
        {
            sprite.enabled = Random.value > 0.25f;
            sprite.flipX = Random.value > 0.5f;
            yield return new WaitForSeconds(1f / flickerRate);
        }
    }

    void OnTriggerEnter2D(Collider2D other) => TryStun(other);
    void OnTriggerStay2D(Collider2D other)  => TryStun(other);

    void TryStun(Collider2D other)
    {
        if (!IsOn || stunDuration <= 0f) return;
        var pc = other.GetComponentInParent<PlayerController2D>();
        if (pc == null || !pc.InputEnabled) return;
        if (stunned.Contains(pc)) return;               // already zapped recently
        StartCoroutine(Stun(pc));
        if (!string.IsNullOrEmpty(zapSfx)) AudioManager.Instance?.PlaySFX(zapSfx);
    }

    IEnumerator Stun(PlayerController2D pc)
    {
        stunned.Add(pc);
        pc.InputEnabled = false;
        var rb = pc.GetComponent<Rigidbody2D>();
        if (rb) rb.linearVelocity = new Vector2(0f, rb.linearVelocity.y);
        yield return new WaitForSeconds(stunDuration);
        var hp = pc.GetComponent<Health>();
        if (hp == null || !hp.IsDead) pc.InputEnabled = true;
        yield return new WaitForSeconds(0.5f);          // grace before it can stun again
        stunned.Remove(pc);
    }
}