using System; using AppleHills.Core.Settings; using Core; using Input; using Interactions; using System.Threading.Tasks; using Bootstrap; using PuzzleS; using UnityEngine; using Core.SaveLoad; // Added for IInteractionSettings namespace Levels { /// /// Handles switching into minigame levels when interacted with. Applies switch data and triggers scene transitions. /// public class MinigameSwitch : MonoBehaviour { /// /// Data for this level switch (target scene, icon, etc). /// public LevelSwitchData switchData; private SpriteRenderer _iconRenderer; private Interactable _interactable; // Settings reference private IInteractionSettings _interactionSettings; private bool _isActive = true; /// /// Unity Awake callback. Sets up icon, interactable, and event handlers. /// void Awake() { gameObject.SetActive(false); // Start inactive BootCompletionService.RegisterInitAction(InitializePostBoot); _isActive = true; if (_iconRenderer == null) _iconRenderer = GetComponent(); _interactable = GetComponent(); if (_interactable != null) { _interactable.characterArrived.AddListener(OnCharacterArrived); } // Initialize settings reference _interactionSettings = GameManager.GetSettingsObject(); ApplySwitchData(); // --- Save state loading logic --- if (SaveLoadManager.Instance != null) { if (SaveLoadManager.Instance.IsSaveDataLoaded) { ApplySavedMinigameStateIfAvailable(); } else { SaveLoadManager.Instance.OnLoadCompleted += OnSaveDataLoadedHandler; } } } private void OnDestroy() { PuzzleManager.Instance.OnAllPuzzlesComplete -= HandleAllPuzzlesComplete; if (_interactable != null) { _interactable.characterArrived.RemoveListener(OnCharacterArrived); } if (SaveLoadManager.Instance != null) { SaveLoadManager.Instance.OnLoadCompleted -= OnSaveDataLoadedHandler; } } // Apply saved state if present in the SaveLoadManager private void ApplySavedMinigameStateIfAvailable() { var data = SaveLoadManager.Instance?.currentSaveData; if (data?.unlockedMinigames != null && switchData != null && data.unlockedMinigames.Contains(switchData.targetLevelSceneName)) { gameObject.SetActive(true); } } // Event handler for when save data load completes private void OnSaveDataLoadedHandler(string slot) { ApplySavedMinigameStateIfAvailable(); if (SaveLoadManager.Instance != null) { SaveLoadManager.Instance.OnLoadCompleted -= OnSaveDataLoadedHandler; } } private void HandleAllPuzzlesComplete(PuzzleS.PuzzleLevelDataSO _) { // Unlock and save if (switchData != null) { var unlocked = SaveLoadManager.Instance.currentSaveData.unlockedMinigames; string minigameName = switchData.targetLevelSceneName; if (!unlocked.Contains(minigameName)) { unlocked.Add(minigameName); } } gameObject.SetActive(true); } #if UNITY_EDITOR /// /// Unity OnValidate callback. Ensures icon and data are up to date in editor. /// void OnValidate() { if (_iconRenderer == null) _iconRenderer = GetComponent(); ApplySwitchData(); } #endif /// /// Applies the switch data to the level switch (icon, name, etc). /// public void ApplySwitchData() { if (switchData != null) { if (_iconRenderer != null) _iconRenderer.sprite = switchData.mapSprite; gameObject.name = switchData.targetLevelSceneName; // Optionally update other fields, e.g. description } } /// /// Handles the start of an interaction (shows confirmation menu and switches the level if confirmed). /// private void OnCharacterArrived() { if (switchData == null || string.IsNullOrEmpty(switchData.targetLevelSceneName) || !_isActive) return; var menuPrefab = _interactionSettings?.MinigameSwitchMenuPrefab; if (menuPrefab == null) { Debug.LogError("MinigameSwitchMenu prefab not assigned in InteractionSettings!"); return; } // Spawn the menu overlay (assume Canvas parent is handled in prefab setup) var menuGo = Instantiate(menuPrefab); var menu = menuGo.GetComponent(); if (menu == null) { Debug.LogError("MinigameSwitchMenu component missing on prefab!"); Destroy(menuGo); return; } // Setup menu with data and callbacks menu.Setup(switchData, OnLevelSelectedWrapper, OnMenuCancel); _isActive = false; // Prevent re-triggering until menu is closed // Switch input mode to UI only InputManager.Instance.SetInputMode(InputMode.UI); } private void OnLevelSelectedWrapper() { _ = OnLevelSelected(); } private async Task OnLevelSelected() { var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress); } private void OnMenuCancel() { _isActive = true; // Allow interaction again if cancelled InputManager.Instance.SetInputMode(InputMode.GameAndUI); } private void InitializePostBoot() { PuzzleManager.Instance.OnAllPuzzlesComplete += HandleAllPuzzlesComplete; } } }