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

/// <summary>
/// GAME 1303 Tier 2 — "This is what hurts you." A trigger that damages Hurtboxes
/// on the opposing team while it's active.
///
/// SETUP
///  1. Empty CHILD of the attacker (e.g. "SwordHitbox") positioned in front of them.
///  2. BoxCollider2D (Is Trigger ON) + this script. Start with the child DISABLED
///     in the Inspector (uncheck the GameObject). MeleeAttack turns it on for the
///     swing window; BossController and EnemyPatrol can too.
///  3. Set Target Team to whoever this should hurt.
///  4. Layer: "Hitbox" (see Hurtbox notes on the collision matrix).
///
/// Each time the hitbox is enabled it forgets who it already hit, so one swing
/// hits each enemy once, but the next swing can hit them again.
///
/// A hitbox that's always on (e.g. an enemy's body) works too — set Repeat Delay
/// so it re-hits every N seconds while overlapping.
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class Hitbox : MonoBehaviour
{
    public Team targetTeam = Team.Enemy;
    public int damage = 1;

    [Header("Knockback")]
    public float knockbackForce = 6f;
    public float knockbackUpward = 3f;

    [Header("Repeat (for always-on hitboxes)")]
    [Tooltip("0 = hit each target once per activation. >0 = re-hit every N seconds.")]
    public float repeatDelay = 0f;

    [Header("Events")]
    public UnityEvent<Hurtbox> OnHit;   // ComboCounter.RegisterHit, hit SFX, hit-stop, particles

    private readonly Dictionary<Hurtbox, float> lastHitTime = new Dictionary<Hurtbox, float>();
    private ComboCounter combo;

    void Awake()
    {
        GetComponent<Collider2D>().isTrigger = true;
        combo = GetComponentInParent<ComboCounter>();
    }

    void OnEnable()
    {
        lastHitTime.Clear();
    }

    void OnTriggerEnter2D(Collider2D other) => TryHit(other);
    void OnTriggerStay2D(Collider2D other)  { if (repeatDelay > 0f) TryHit(other); }

    void TryHit(Collider2D other)
    {
        Hurtbox hb = other.GetComponent<Hurtbox>();
        if (hb == null) return;
        if (hb.team != targetTeam && hb.team != Team.Neutral) return;

        // Already hit this target this activation?
        if (lastHitTime.TryGetValue(hb, out float t))
        {
            if (repeatDelay <= 0f) return;
            if (Time.time - t < repeatDelay) return;
        }

        int finalDamage = damage;
        if (combo != null) finalDamage = Mathf.RoundToInt(damage * combo.DamageMultiplier);

        Vector2 origin = transform.parent != null ? (Vector2)transform.parent.position : (Vector2)transform.position;
        if (hb.ReceiveHit(finalDamage, origin, knockbackForce, knockbackUpward))
        {
            lastHitTime[hb] = Time.time;
            OnHit?.Invoke(hb);
        }
    }
}