using System.Collections.Generic;
using Assets.Source.General;
using Assets.Source.Patterns.ScriptableObjects;
using Assets.Source.Settings;
using Assets.Source.Utils;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Assets.Source.CommonWorkers
{
    public class WorkerScenes : Worker
    {
        private Dictionary<GameObject, GameObject> _spawnedCommonLookup = new Dictionary<GameObject, GameObject>();
        private static Dictionary<GameSceneType, Scene> _scenesLookup = new Dictionary<GameSceneType, Scene>();

        private static Scene _commonScene;
        public static Scene CommonScene
            => _commonScene.isLoaded ? _commonScene : (_commonScene = SceneManager.CreateScene("Common"));

        public Scene this[GameSceneType type] => _scenesLookup[type];

        public GameSceneType LastActiveSceneType { get; private set; }

        protected override void VClearContent()
        {
            base.VClearContent();
            _scenesLookup.Clear();
        }

        protected override void VInit()
        {
            base.VInit();

            //MoveToCommon(GameCamera.Instance.gameObject);

            HandleFirstScene();
        }

        private void HandleFirstScene()
        {
            var buildInd = SceneManager.GetActiveScene().buildIndex;
            LastActiveSceneType = Get.CoreSettings.GetSceneByIndex(buildInd);
            _scenesLookup.Add(LastActiveSceneType, SceneManager.GetSceneByBuildIndex(buildInd));
            EBus.Publish(new EventSceneLoaded
            {
                Type = LastActiveSceneType
            });
        }

        public void UseSceneEntry(SceneEntry entry)
        {
            foreach (var p in entry.CommonPrefabs)
            {
                if (_spawnedCommonLookup.ContainsKey(p))
                    continue;
                var go = Instantiate(p);
                _spawnedCommonLookup.Add(p, go);
                MoveToCommon(go);
            }
            foreach (var sceneType in entry.ScenesToPreload)
                TryPreloadScene(sceneType);
        }

        public void TryPreloadScene(GameSceneType type)
        {
            if (_scenesLookup.ContainsKey(type))
                return;
            var buildInd = Get.CoreSettings.GetSceneByType(type);
            SceneManager.LoadScene(buildInd, LoadSceneMode.Additive);
            _scenesLookup.Add(type, SceneManager.GetSceneByBuildIndex(buildInd));
        }

        public void ActivateScene(GameSceneType type)
        {
            if (LastActiveSceneType == type)
                return;
            TryPreloadScene(type);
            LastActiveSceneType = type;

            EBus.Publish(new EventSceneLoaded
            {
                Type = type
            });

            UIUtils.CloseAllDialogues();
        }

        public void ReloadScene()
        {
            //LastActiveSceneType = GameSceneType.Undefined;
            //var ind = _scenesLookup[LastActiveSceneType].buildIndex;
            //SceneManager.UnloadSceneAsync(_scenesLookup[LastActiveSceneType]);
            SceneManager.LoadScene(_scenesLookup[LastActiveSceneType].buildIndex);
        }
        
        public static void MoveToCommon(GameObject go)
        {
            go.transform.SetParent(null);
            SceneManager.MoveGameObjectToScene(go, CommonScene);
        }
    }
}
