using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using System; public class LevelControl : MonoBehaviour { [System.Serializable] public class MateriLevelPair { public string materiName; public List levelNames; } public static LevelControl Instance; public List levelSceneNames; public string currentMateriName; public List materiLevelPairs; private Dictionary> materiToLevels = new Dictionary>(); private Dictionary cachedUnlockedLevels = new Dictionary(); private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); BuildMateriDictionary(); } else { Destroy(gameObject); } } private void BuildMateriDictionary() { materiToLevels.Clear(); foreach (var pair in materiLevelPairs) { if (!materiToLevels.ContainsKey(pair.materiName)) { materiToLevels[pair.materiName] = new List(pair.levelNames); } } } /// /// Dipanggil dari InputUserController setelah login berhasil /// public void LoadLevelsFromFirebase(string kodeLogin) { StartCoroutine(LoadAllProgressFromFirebase(kodeLogin)); } private IEnumerator LoadAllProgressFromFirebase(string kodeLogin) { cachedUnlockedLevels.Clear(); foreach (var materi in materiToLevels.Keys) { bool done = false; DBManager.LoadLevelProgress(kodeLogin, materi, (progress) => { if (progress <= 0) progress = 1; cachedUnlockedLevels[materi] = progress; done = true; }); yield return new WaitUntil(() => done); } Debug.Log($"[LevelControl] Semua progress level dari Firebase telah dimuat."); } public string NextLevel(string currentScene) { string currentMateri = GetMateriByLevel(currentScene); if (string.IsNullOrEmpty(currentMateri)) return null; if (materiToLevels.TryGetValue(currentMateri, out List levels)) { int index = levels.IndexOf(currentScene); if (index >= 0 && index < levels.Count - 1) { return levels[index + 1]; } } return null; } public void UnlockedNewLevel() { string currentScene = SceneManager.GetActiveScene().name; string currentMateri = GetMateriByLevel(currentScene); if (string.IsNullOrEmpty(currentMateri)) return; if (materiToLevels.TryGetValue(currentMateri, out List levels)) { int index = levels.IndexOf(currentScene); if (index >= 0 && index < levels.Count - 1) { string kodeLogin = TestManager.Instance?.kodeLogin ?? "default"; int currentUnlocked = GetUnlockedLevel(currentMateri); if (currentUnlocked <= index + 1) { DBManager.SaveUnlockedLevel(kodeLogin, currentMateri, index + 2); cachedUnlockedLevels[currentMateri] = index + 2; Debug.Log($"[LevelControl] Level {index + 2} unlocked untuk {kodeLogin} pada materi {currentMateri}"); } } } } public int GetUnlockedLevel(string materiName = null) { if (materiName == null) materiName = currentMateriName; if (cachedUnlockedLevels.TryGetValue(materiName, out int unlocked)) return unlocked; return 1; } public string GetMateriByLevel(string levelName) { foreach (var pair in materiToLevels) { if (pair.Value.Contains(levelName)) return pair.Key; } return null; } public bool IsLastLevelOfMateri(string levelName) { string materi = GetMateriByLevel(levelName); if (materi == null) return false; List levels = materiToLevels[materi]; int index = levels.FindIndex(l => l.Trim().Equals(levelName.Trim(), StringComparison.OrdinalIgnoreCase)); return index == levels.Count - 1; } public List GetLevelsInMateri(string materiName) { if (materiToLevels.ContainsKey(materiName)) return materiToLevels[materiName]; return new List(); } public bool AllLevelUnlocked(string materiName) { if (!materiToLevels.ContainsKey(materiName)) return false; int unlocked = GetUnlockedLevel(materiName); int totalLevel = materiToLevels[materiName].Count; return unlocked >= totalLevel; } }