using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UDB;
using Eflatun.SceneReference;
using System.Reflection;

public class SceneKeeperHelper: MonoBehaviour
{
    #region Fields/Properties
    [SerializeField]
    private bool debug = false;
    public List<SceneReference> scenesToKeepIn = new List<SceneReference>();

    public List<SceneReference> activeScenesToKeepIn = new List<SceneReference>();
    private string className => this.GetType().ToString();
    private string debugCategory => "#" + className + "#";
    #endregion

    #region Unity Methods
    // Called when the script instance is being loaded
    void Awake()
    {
        DontDestroyOnLoad(gameObject);
        SceneManager.activeSceneChanged += ActiveSceneChange;
        SceneManager.sceneUnloaded += OnSceneUnloaded;
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    // Called when the MonoBehaviour will be destroyed
    void OnDestroy()
    {
        SceneManager.activeSceneChanged -= ActiveSceneChange;
        SceneManager.sceneUnloaded -= OnSceneUnloaded;
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }
    #endregion

    #region Private Methods

    private void CheckForDestory(Scene activeScene)
    {
        for (int j = 0; j < activeScenesToKeepIn.Count; j += 1) {
            if (activeScenesToKeepIn[j].Name.IsEqual(activeScene.name)) {
                return;
            }
        }
        if (debug) {
            Debug.Log(debugCategory + className + " at " + MethodBase.GetCurrentMethod().Name + "\n" +
                      "Destroying singleton of " + gameObject.name);
        }

        gameObject.DestoryAppropriately();
    }


    private void ActiveSceneChange(Scene previousScene, Scene activeScene)
    {
        if (debug) {
            Debug.Log(debugCategory + className + " at " + MethodBase.GetCurrentMethod().Name + "\n" +
                  "previousScene: " + previousScene.name + "\n" +
                  "activeScene: " + activeScene.name);
        }

        if (activeScenesToKeepIn.Count < 1) {
            return;
        }
        CheckForDestory(activeScene);
    }

    private void CheckForDestroy()
    {
        for (int i = 0; i < SceneManager.sceneCount; i++) {
            string sceneName = SceneManager.GetSceneAt(i).name;
            for (int j = 0; j < scenesToKeepIn.Count; j++) {
                if (scenesToKeepIn [j].Name.IsEqual(sceneName)) {
                    return;
                }
            }
        }

        if (debug) {
            Debug.Log(debugCategory + className + " at " + MethodBase.GetCurrentMethod().Name + "\n" +
                      "Destroying singleton of " + gameObject.name);
        }

        gameObject.DestoryAppropriately();
    }

    private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if (scenesToKeepIn.Count < 1) {
            return;
        }
        CheckForDestroy();
    }

    private void OnSceneUnloaded(Scene scene)
    {
        if (scenesToKeepIn.Count < 1) {
            return;
        }
        CheckForDestroy();
    }
    #endregion

    #region Public Methods
    #endregion
}