using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public enum GameScenes
{
    Title,
    Main,
    Cooking,
    CookingResults,
    FryingPanExplanation,
    CornField,
    Reinforcement,
    ReinforcementDetail,
    Recipe,
    RecipeChoice,
    marketing,
    shopping,
    ShoppingExplanation,
    Purchase,
    ExchangeAchievement,
    ProductManagement,
    PopcornDescription,
    Tasting,
    Mission,
    MissionAchievement,
    BulkOrder,
    BulkOrderAchievement,
    BulkOrderCancel,
    BulkOrderTelephone,
    StoreLevel,
    Conversation,
    Information,
    SettingsDialog,
    DebugOption,
    WatchMovieFailure,
    WatchMovieCoin,
    WatchMovieCoinGet,
    ApplicationExitConfirmDialog,
    Update,
    HowToPlay,
    AutomaticCookingMovie,
    AutomaticCookingConfirmation,
    AutomaticCookingComplete,
    AutomaticCookingCaution,
    CustomizationPurchase,
    CustomizationDetails,
    Customize,
    CustomizeExplanation,
    MiniGame,
    WatchMovieMiniGame,
}

public enum SceneType
{
    Default,
    ManualUnloadOnly
}

public sealed class TransitionManager : SingletonMonoBehaviour<TransitionManager>
{
    private List<(SceneType, GameScenes)> loadedSceneList = new List<(SceneType, GameScenes)>();

//     void Awake(){
// #if UNITY_EDITOR
//         GameScenes currentScene;
//         try{
//             currentScene = (GameScenes)Enum.Parse(typeof(GameScenes), SceneManager.GetActiveScene().name, false);
//         }catch{
//             currentScene = GameScenes.TransitionManager;
//         }
//         if(currentScene != GameScenes.TransitionManager){
//             loadedSceneList.Add((SceneType.Default, currentScene));
//             SceneManager.LoadScene("TransitionManager", LoadSceneMode.Additive);
//             return ;
//         }
// #endif

//         TransitionManager.Instance.LoadScene(GameScenes.Main);
//     }

    public void LoadScene(GameScenes scene)
    {
        SceneManager.LoadScene(scene.ToString());
//        StartCoroutine(_LoadScene(scene));
    }

//     private IEnumerator _LoadScene(GameScenes scene){
// /*
//         yield return StartCoroutine(_ResetScene());
//         yield return Resources.UnloadUnusedAssets();
//         GC.Collect();
//         yield return StartCoroutine(_LoadSceneAdditive(scene, SceneType.Default));
//         SceneManager.SetActiveScene(SceneManager.GetSceneByName(scene.ToString()));
// /*/
//         for(int i = loadedSceneList.Count - 1; i >= 0; --i){
//             if(loadedSceneList[i].Item1 != SceneType.ManualUnloadOnly){
//                 SceneManager.UnloadScene(loadedSceneList[i].Item2.ToString());
//                 loadedSceneList.RemoveAt(i);
//             }
//         }
//         Resources.UnloadUnusedAssets();
//         GC.Collect();
//         SceneManager.LoadScene(scene.ToString(), LoadSceneMode.Additive);
//         loadedSceneList.Add((SceneType.Default, scene));
//         while(true){
//             yield return null;
//             try{
//                 SceneManager.SetActiveScene(SceneManager.GetSceneByName(scene.ToString()));
//             }catch(Exception){
//                 continue;
//             }
//             break;
//         }
// //*/
//     }
    public void LoadSceneAdditive(GameScenes scene, SceneType sceneType = SceneType.Default)
    {
        StartCoroutine(_LoadSceneAdditive(scene, sceneType));
    }

    private IEnumerator _LoadSceneAdditive(GameScenes scene, SceneType sceneType)
    {
        yield return SceneManager.LoadSceneAsync(scene.ToString(), LoadSceneMode.Additive);
        loadedSceneList.Add((sceneType, scene));
    }

    public void UnloadScene(GameScenes scene)
    {
        UnloadScene(scene, ActionExtensions.EmptyAction);
    }

    public void UnloadScene(GameScenes scene, Action callback)
    {
        StartCoroutine(_UnloadScene(scene, callback));
    }

    private IEnumerator _UnloadScene(GameScenes scene, Action callback)
    {
        yield return SceneManager.UnloadSceneAsync(scene.ToString());
        loadedSceneList.Remove(loadedSceneList.Find(t => t.Item2 == scene));
        callback();
    }

    private IEnumerator _ResetScene()
    {
        List<Coroutine> coroutineList = new List<Coroutine>();
        for (int i = loadedSceneList.Count - 1; i >= 0; --i)
        {
            if (loadedSceneList[i].Item1 != SceneType.ManualUnloadOnly)
            {
                coroutineList.Add(StartCoroutine(_UnloadScene(loadedSceneList[i].Item2, ActionExtensions.EmptyAction)));
                loadedSceneList.RemoveAt(i);
            }
        }

        foreach (var coroutine in coroutineList)
        {
            yield return coroutine;
        }
    }

    public bool Exists(GameScenes scene)
    {
        foreach (var tuple in loadedSceneList)
        {
            if (tuple.Item2 == scene) return true;
        }

        return false;
    }
}
