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

/// <summary>
/// GAME 1303 Tier 4 — The end of the level. Walk in, the level completes, the next one loads.
/// Every game with more than one scene needs this.
///
/// SETUP
///  1. Sprite (flag, portal, door) + Collider2D (Is Trigger) + this script.
///  2. Requirement (same idea as Door): None, or Collect N of an ItemType, or a Flag.
///     Commission Witch: require all ingredients. Roach Invasion: all plants.
///  3. Destination:
///       NextInBuild  – SceneLoader.LoadNext()
///       NamedScene   – type the scene name (must be in Build Settings)
///       StayHere     – only fires the events (for a boss arena / hub return you wire yourself)
///  4. Delay lets a win jingle and animation play before the scene changes.
///  5. It calls GameManager.LevelComplete() first, so your win panel shows and the timer stops.
///
/// Zap Attack's locked 5th level: use a Door in front of the exit rather than the exit's
/// own requirement, so the player can see the goal and understand what's missing.
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class LevelExit : MonoBehaviour
{
    public enum Destination { NextInBuild, NamedScene, StayHere }

    [Header("Requirement")]
    public Door.Requirement requirement = Door.Requirement.None;
    public ItemType requiredItem;
    public int requiredCount = 1;
    public string requiredFlag = "";

    [Header("Destination")]
    public Destination destination = Destination.NextInBuild;
    public string sceneName = "";
    public float delay = 1f;

    [Header("Feedback")]
    public string completeSfx = "level_complete";
    public string lockedSfx = "door_locked";
    [Tooltip("Set this flag when the level is cleared (e.g. 'sector1_level3_done').")]
    public string setFlagOnComplete = "";

    public UnityEvent OnCompleted;
    public UnityEvent OnRefused;

    private bool used;

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

    void OnTriggerEnter2D(Collider2D other)
    {
        if (used || !other.CompareTag("Player")) return;
        if (!RequirementMet()) { Refuse(); return; }
        used = true;
        StartCoroutine(Complete());
    }

    bool RequirementMet()
    {
        switch (requirement)
        {
            case Door.Requirement.Collect:
                if (requiredItem == null) return true;
                int have = CollectionTracker.Instance != null ? CollectionTracker.Instance.GetCount(requiredItem) : 0;
                return have >= requiredCount;
            case Door.Requirement.Flag:
                if (string.IsNullOrEmpty(requiredFlag)) return true;
                return ChoiceFlagManager.Instance == null || ChoiceFlagManager.Instance.HasFlag(requiredFlag);
            default:
                return true;
        }
    }

    void Refuse()
    {
        if (!string.IsNullOrEmpty(lockedSfx)) AudioManager.Instance?.PlaySFX(lockedSfx);
        OnRefused?.Invoke();
    }

    IEnumerator Complete()
    {
        if (!string.IsNullOrEmpty(completeSfx)) AudioManager.Instance?.PlaySFX(completeSfx);
        if (!string.IsNullOrEmpty(setFlagOnComplete)) ChoiceFlagManager.Instance?.SetFlag(setFlagOnComplete);

        GameManager.Instance?.LevelComplete();
        OnCompleted?.Invoke();

        if (destination == Destination.StayHere) yield break;

        yield return new WaitForSeconds(delay);

        if (destination == Destination.NamedScene && !string.IsNullOrEmpty(sceneName))
            SceneLoader.Instance?.LoadScene(sceneName);
        else
            SceneLoader.Instance?.LoadNext();
    }
}