#nullable enable
using System;
using Nox.Core;
using Jovian.SaveSystem;
using UnityEngine;
using UnityEngine.AddressableAssets;
using Object = UnityEngine.Object;
using PlayMode = Nox.Core.PlayMode;

namespace Nox.Game.UI {
    public class PauseMenuView: IMenuView {
        private readonly GameDataState gameDataState;
        private readonly ISaveSystem saveSystem;
        private readonly Func<NoxSavedDataSet?> captureSaveData;
        private PauseMenuReferences? pauseMenu;
        private PauseMenuPrefabs? pauseMenuPrefabs;

        public PauseMenuView(GameDataState gameDataState, ISaveSystem saveSystem, Func<NoxSavedDataSet?> captureSaveData) {
            this.gameDataState = gameDataState;
            this.saveSystem = saveSystem;
            this.captureSaveData = captureSaveData;
            pauseMenu ??= Object.FindFirstObjectByType<PauseMenuReferences>();
            if(pauseMenu) {
                Hide();
            }
        }

        public void Initialize() {
            pauseMenuPrefabs ??= Addressables.LoadAssetAsync<PauseMenuPrefabs>("PauseMenuPrefabs").WaitForCompletion();
            if(!pauseMenu) {
                pauseMenu = Object.Instantiate(pauseMenuPrefabs.pauseMenuReferencesPrefab);
                pauseMenu?.resumeButton.onClick.AddListener(() => {gameDataState.ChangePlayMode(gameDataState.PreviousPlayMode);});
                pauseMenu?.exitButton.onClick.AddListener(() => {
                    OnSaveRequested();
                    gameDataState.ChangeGameState(GameState.MainMenu);
                });
                pauseMenu?.saveButton.onClick.AddListener(OnSaveRequested);
            }
            Show();
        }

        private void OnSaveRequested() {
            if(string.IsNullOrEmpty(gameDataState.activeSessionId)) {
                Debug.LogWarning("[PauseMenuView] No active session. Cannot save.");
                return;
            }

            var data = captureSaveData();
            if(data == null) {
                Debug.LogWarning("[PauseMenuView] No save data to capture.");
                return;
            }

            saveSystem.Save(gameDataState.activeSessionId, data, SaveSlotType.Auto);
        }

        public void Show() {
            pauseMenu?.gameObject.SetActive(true);
        }

        public void Hide() {
            pauseMenu?.gameObject.SetActive(false);
        }

        public void Tick() { }
    }

}
