using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// GAME 1303 Tier 6 — Works out which ending the player earned and goes there.
/// Commission Witch ("different endings based on how many ingredients you collect"),
/// Anabasis, Detective Liz.
///
/// SETUP
/// 1. Empty GameObject + this script, in the scene where the game can end.
/// 2. Add an Ending entry per outcome. Each one can require:
/// Require Flags – "saved_the_cat, !broke_the_mirror"
/// Item / Min Count – at least N of an ItemType from the CollectionTracker
/// Min Counter – a ChoiceFlagManager counter is at least N
/// An ending with NO conditions is a valid fallback.
/// 3. ORDER MATTERS: the FIRST ending whose conditions all pass is chosen. Put the
/// hardest, most specific ending at the top and the "you just finished" one last.
/// 4. Each ending can load a scene, set a flag, and fire an event (show a panel,
/// play music, roll credits).
/// 5. Trigger it: wire LevelExit.OnCompleted or a boss's OnBossDefeated to
/// EndingSelector.ChooseEnding.
///
/// Endings List: EndingSelector records each ending the player has seen under
/// "ending_seen_<id>" in the flag manager, so an ending gallery is just a set of
/// flag checks (Andraya's mood board has an ENDING LIST in the menu — this is that).
/// </summary>
public class EndingSelector : MonoBehaviour
{
[System.Serializable]
public class Ending
{
public string endingId = "good";
public string displayName = "The Good Ending";
[TextArea(2, 4)] public string description = "";
[Header("Conditions (all must pass; empty = always passes)")]
public string requireFlags = "";
public ItemType requiredItem;
public int minItemCount = 0;
public string counterName = "";
public int minCounterValue = 0;
[Header("What happens")]
public string loadScene = "";
public string setFlag = "";
public DialogueData epilogue;
public UnityEvent onChosen;
}
[Tooltip("Checked top to bottom — first match wins. Put the fallback LAST.")]
public List<Ending> endings = new List<Ending>();
public float delayBeforeScene = 0.5f;
[Tooltip("Play the ending's epilogue dialogue before loading its scene.")]
public bool waitForEpilogue = true;
public DialogueRunner dialogueRunner;
[Header("Events")]
public UnityEvent<string> OnEndingChosen; // ending id
public UnityEvent OnNoEndingMatched;
public Ending ChosenEnding { get; private set; }
/// <summary>Wire LevelExit.OnCompleted / boss defeat here.</summary>
public void ChooseEnding()
{
foreach (var e in endings)
{
if (!Matches(e)) continue;
Apply(e);
return;
}
Debug.LogWarning("EndingSelector: no ending matched. Add a fallback with no conditions.");
OnNoEndingMatched?.Invoke();
}
bool Matches(Ending e)
{
if (!string.IsNullOrWhiteSpace(e.requireFlags))
{
if (ChoiceFlagManager.Instance != null && !ChoiceFlagManager.Instance.HasAll(e.requireFlags))
return false;
}
if (e.requiredItem != null && e.minItemCount > 0)
{
int have = CollectionTracker.Instance != null ? CollectionTracker.Instance.GetCount(e.requiredItem) : 0;
if (have < e.minItemCount) return false;
}
if (!string.IsNullOrEmpty(e.counterName) && e.minCounterValue > 0)
{
int c = ChoiceFlagManager.Instance != null ? ChoiceFlagManager.Instance.GetCount(e.counterName) : 0;
if (c < e.minCounterValue) return false;
}
return true;
}
void Apply(Ending e)
{
ChosenEnding = e;
if (!string.IsNullOrEmpty(e.setFlag)) ChoiceFlagManager.Instance?.SetFlag(e.setFlag);
ChoiceFlagManager.Instance?.SetFlag("ending_seen_" + e.endingId);
e.onChosen?.Invoke();
OnEndingChosen?.Invoke(e.endingId);
if (e.epilogue != null && dialogueRunner != null)
{
dialogueRunner.StartDialogue(e.epilogue);
if (waitForEpilogue)
{
dialogueRunner.OnDialogueEnded.AddListener(LoadChosenScene);
return;
}
}
Invoke(nameof(LoadChosenScene), delayBeforeScene);
}
void LoadChosenScene()
{
if (ChosenEnding == null || string.IsNullOrEmpty(ChosenEnding.loadScene)) return;
SceneLoader.Instance?.LoadScene(ChosenEnding.loadScene);
}
/// <summary>For an ending gallery: has the player seen this one?</summary>
public static bool HasSeen(string endingId) =>
ChoiceFlagManager.Instance != null && ChoiceFlagManager.Instance.HasFlag("ending_seen_" + endingId);
}