using System;
using Eflatun.SceneReference;
using UnityEditor;

#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
using UnityEngine;
using UnityEngine.SceneManagement;

namespace KitsuneCafe.Scene
{
    [ExecuteInEditMode]
    public class Subscene : MonoBehaviour
    {
        [SerializeField]
        private SceneReference scene;

        [SerializeField]
        private bool loadOnStart;

        private AsyncOperation sceneLoadOperation;

        public event Action SceneLoaded = delegate { };
        private bool isLoading = false;
        private bool isLoaded = false;

        private void Start()
        {
#if UNITY_EDITOR
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
            if (!EditorApplication.isPlayingOrWillChangePlaymode)
            {
                LoadPreviewScene();
            }
#else

            if (loadOnStart && !isLoading)
            {
                Load();
                isLoading = true;
            }
#endif
        }

        private void OnPlayModeStateChanged(PlayModeStateChange change)
        {
            switch (change)
            {
                case PlayModeStateChange.EnteredEditMode:
                    LoadPreviewScene();
                    break;
                case PlayModeStateChange.ExitingEditMode:
                    UnloadPreviewScene();
                    break;
            }
        }

#if UNITY_EDITOR
        private void LoadPreviewScene()
        {
            if (scene.Path == null || SceneManager.GetSceneByPath(scene.Path).isLoaded)
            {
                return;
            }

            EditorSceneManager.OpenScene(scene.Path, OpenSceneMode.Additive);
        }

        private void UnloadPreviewScene()
        {
            if (scene.LoadedScene != null)
            {
                // EditorSceneManager.CloseScene(scene.LoadedScene, false);
                if (loadOnStart)
                {
                    Load();
                }
            }
        }

#endif

        private void Load()
        {
            if (sceneLoadOperation == null)
            {
                sceneLoadOperation = SceneManager.LoadSceneAsync(
                    scene.BuildIndex,
                    LoadSceneMode.Additive
                );

                sceneLoadOperation.completed += OnCompleted;
            }
        }

        private void OnCompleted(AsyncOperation _operation)
        {
            isLoaded = true;
            SceneLoaded.Invoke();
        }
    }
}
