﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneManager : SingletonBase<SceneManager>
{
    public string scenePrefabResourceRoot = "Prefabs/Scenes/";
    public string sceneUIPrefabResourceRoot = "Prefabs/UI/Scenes/";
    public string startingUIScene = "Main";
    public string startingScene = "Home";

    private static SceneManager sceneManager;
    private Dictionary<string, GameObject> sceneUIs = new Dictionary<string, GameObject>();
    private Dictionary<string, GameObject> scenes = new Dictionary<string, GameObject>();
    private string currentSceneUI = null;
    private string currentScene = null;

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

        sceneManager = instance as SceneManager;
    }

    private void Start()
    {
        StartScene(startingScene, startingUIScene);
    }

    private void OnEnable()
    {
        Action.OnPerformed += SceneChange;
        //DogStatisticsHandler.OnIdle += ReloadScene;
        DogManager.OnDeath += Start;
    }

    private void OnDisable()
    {
        Action.OnPerformed -= SceneChange;
        //DogStatisticsHandler.OnIdle -= ReloadScene;
        DogManager.OnDeath -= Start;
    }

    private void SceneChange(Action action)
    {
        StopAllScenes();

        if (action.nextScene != null && action.nextScene != "")
        {
            StartScene(action.nextScene);
        }
        if (currentScene != null && currentScene != "")
        {
            StartScene(currentScene);
        }


        if (action.nextSceneUI != null && action.nextSceneUI != "")
        {
            StartSceneUI(action.nextSceneUI, action);
        }

        if (currentSceneUI != null && currentSceneUI != "")
        {
            StartSceneUI(currentSceneUI);
        }
    }

    private void StartScene(string sceneName, string sceneUIName, Action triggeringAction = null)
    {
        StopAllScenes();
        StartScene(sceneName);
        StartSceneUI(sceneUIName, triggeringAction);
    }

    private void StartScene(string sceneName)
    {
        if (scenes.ContainsKey(sceneName))
        {
            scenes[sceneName].SetActive(true);
        }
        else
        {
            string startingSceneResourceLocation = SceneToResourceLocation(sceneName);

            GameObject sceneGameObject = Instantiate(Resources.Load<GameObject>(startingSceneResourceLocation));
            scenes[sceneName] = sceneGameObject;
        }

        currentScene = sceneName;
    }

    private void StartSceneUI(string sceneUIName, Action triggeringAction = null)
    {
        if (sceneUIs.ContainsKey(sceneUIName))
        {
            sceneUIs[sceneUIName].SetActive(true);
        }
        else
        {

            string startingSceneUIResourceLocation = SceneUIToResourceLocation(sceneUIName);

            GameObject sceneUIGameObject = Instantiate(Resources.Load<GameObject>(startingSceneUIResourceLocation), GameManager.UIRoot);
            sceneUIs[sceneUIName] = sceneUIGameObject;
        }

        if (triggeringAction != null)
        {
            SceneUI sceneUI = sceneUIs[sceneUIName].GetComponent<SceneUI>();

            if (sceneUI != null)
            {
                sceneUI.TriggeringAction = triggeringAction;
            }
        }

        currentSceneUI = sceneUIName;
    }

    private void StopAllScenes()
    {
        foreach (GameObject scene in sceneUIs.Values)
        {
            scene.SetActive(false);
        }

        foreach (GameObject scene in scenes.Values)
        {
            scene.SetActive(false);
        }
    }

    private string SceneUIToResourceLocation(string scene)
    {
        return sceneUIPrefabResourceRoot + scene;
    }

    private string SceneToResourceLocation(string scene)
    {
        return scenePrefabResourceRoot + scene;
    }

    private void ReloadSceneUI()
    {
        StartScene(currentScene, currentSceneUI);

        if (sceneUIs.ContainsKey(currentSceneUI))
        {
            SceneUI scene = sceneUIs[currentSceneUI].GetComponent<SceneUI>();
            scene.TriggeringAction.Perform();
        }
    }
}
