using Firebase.Auth; using Firebase.Extensions; using Firebase.Firestore; using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using TMPro; using UnityEngine; using static UnityEngine.EventSystems.EventTrigger; namespace BulletHellTemplate { public class UIMapsMenu : MonoBehaviour { [Header("Map Entry Prefabs")] [Tooltip("Prefab for standard map entries in the UI.")] public MapEntry mapEntryPrefab; [Tooltip("Container for standard map entries.")] public Transform mapContainer; [Header("Map Entry Events")] [Tooltip("Prefab for event map entries in the UI.")] public MapEntry eventMapEntryPrefab; [Tooltip("Container for event map entries.")] public Transform eventMapContainer; [Header("Event Map Settings")] [Tooltip("Bypass Firebase check and display all event maps")] public bool alwaysShowEventMap; [Header("UI Elements")] [Tooltip("Text component for error messages")] public TextMeshProUGUI errorMessage; public string difficulty = "Difficulty:"; public NameTranslatedByLanguage[] difficultyTranslated; public string insufficientCurrency = "Insufficient Tickets!"; public NameTranslatedByLanguage[] insufficientCurrencyTranslated; [Header("Firebase References")] private FirebaseFirestore firestore; private FirebaseAuth auth; private List mapEntries = new List(); public static UIMapsMenu Singleton; private string currentLang; private void Awake() { if (Singleton == null) { Singleton = this; InitializeFirebase(); } else { Destroy(gameObject); } } private void OnEnable() { currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage(); StartCoroutine(LoadMapsCoroutine()); } private void InitializeFirebase() { try { auth = FirebaseAuth.DefaultInstance; firestore = FirebaseFirestore.DefaultInstance; } catch (Exception e) { Debug.LogError($"Firebase initialization failed: {e.Message}"); } } private IEnumerator LoadMapsCoroutine() { ClearMapEntries(); if (GameInstance.Singleton == null || GameInstance.Singleton.mapInfoData == null) { Debug.LogError("Missing GameInstance or map data"); yield break; } List allMaps = new List(GameInstance.Singleton.mapInfoData); for (int i = 0; i < allMaps.Count; i++) { MapInfoData currentMap = allMaps[i]; // Handle regular maps if (!currentMap.isEventMap) { MapEntry newEntry = CreateStandardMapEntry(currentMap); ProcessMapUnlockRules(currentMap, i, allMaps); } // Handle event maps else { yield return StartCoroutine(ProcessEventMap(currentMap)); } } } private MapEntry CreateStandardMapEntry(MapInfoData mapData) { MapEntry entry = Instantiate(mapEntryPrefab, mapContainer); string mapNameTranslated = GetTranslatedString(mapData.mapNameTranslated, mapData.mapName, currentLang); string mapDescriptionTranslated = GetTranslatedString(mapData.mapDescriptionTranslated, mapData.mapDescription, currentLang); string _difficultyTranslated = GetTranslatedString(difficultyTranslated,difficulty, currentLang); entry.Setup(mapData,mapNameTranslated,mapDescriptionTranslated,_difficultyTranslated, IsMapUnlocked(mapData)); mapEntries.Add(entry); return entry; } private IEnumerator ProcessEventMap(MapInfoData mapData) { bool shouldDisplay = alwaysShowEventMap; if (!alwaysShowEventMap) { var firebaseTask = GetEventMapStatus(mapData.eventIdName); yield return new WaitUntil(() => firebaseTask.IsCompleted); if (firebaseTask.Result != null && firebaseTask.Result.ContainsKey("active") && (bool)firebaseTask.Result["active"]) { shouldDisplay = true; } } if (shouldDisplay) { MapEntry eventEntry = Instantiate(eventMapEntryPrefab, eventMapContainer); string mapNameTranslated = GetTranslatedString(mapData.mapNameTranslated, mapData.mapName, currentLang); string mapDescriptionTranslated = GetTranslatedString(mapData.mapDescriptionTranslated, mapData.mapDescription, currentLang); string _difficultyTranslated = GetTranslatedString(difficultyTranslated, difficulty, currentLang); eventEntry.Setup(mapData, mapNameTranslated, mapDescriptionTranslated, _difficultyTranslated, IsMapUnlocked(mapData)); mapEntries.Add(eventEntry); } } private void ProcessMapUnlockRules(MapInfoData currentMap, int index, List allMaps) { bool isUnlocked = IsMapUnlocked(currentMap); if (isUnlocked && currentMap.isNeedCurrency && currentMap.canIgnoreMap && index < allMaps.Count - 1) { MapInfoData nextMap = allMaps[index + 1]; if (!IsMapUnlocked(nextMap)) { UnlockMap(nextMap.mapId); } } } private bool IsMapUnlocked(MapInfoData mapData) { return mapData.isUnlocked || PlayerSave.GetUnlockedMaps().Contains(mapData.mapId); } private void UnlockMap(int mapId) { List unlocked = PlayerSave.GetUnlockedMaps(); if (!unlocked.Contains(mapId)) { unlocked.Add(mapId); PlayerSave.SetUnlockedMaps(unlocked); } } private void ClearMapEntries() { foreach (Transform child in mapContainer) Destroy(child.gameObject); foreach (Transform child in eventMapContainer) Destroy(child.gameObject); mapEntries.Clear(); } public void ReloadMaps() { StartCoroutine(LoadMapsCoroutine()); } private string GetTranslatedString(NameTranslatedByLanguage[] translations, string fallback, string currentLang) { if (translations != null) { foreach (var trans in translations) { if (!string.IsNullOrEmpty(trans.LanguageId) && trans.LanguageId.Equals(currentLang) && !string.IsNullOrEmpty(trans.Translate)) { return trans.Translate; } } } return fallback; } private string GetTranslatedString(DescriptionTranslatedByLanguage[] translations, string fallback, string currentLang) { if (translations != null) { foreach (var trans in translations) { if (!string.IsNullOrEmpty(trans.LanguageId) && trans.LanguageId.Equals(currentLang) && !string.IsNullOrEmpty(trans.Translate)) { return trans.Translate; } } } return fallback; } public IEnumerator ShowErrorMessage(float duration) { string errorTranslated = GetTranslatedString(insufficientCurrencyTranslated, insufficientCurrency, currentLang); errorMessage.text = errorTranslated; yield return new WaitForSeconds(duration); errorMessage.text = ""; } public Task> GetEventMapStatus(string eventId) { var tcs = new TaskCompletionSource>(); if (firestore == null) { Debug.LogError("Firestore not initialized!"); tcs.SetResult(null); return tcs.Task; } firestore.Collection("EventMaps").Document(eventId).GetSnapshotAsync() .ContinueWithOnMainThread(task => { if (task.IsFaulted) { Debug.LogError($"Event map check error: {task.Exception}"); tcs.SetResult(null); return; } DocumentSnapshot snapshot = task.Result; tcs.SetResult(snapshot.Exists ? snapshot.ToDictionary() : null); }); return tcs.Task; } } }