using System;

namespace Celeste.Mod.LoungeMod;

public class LoungeModModule : EverestModule {
    public static LoungeModModule Instance { get; private set; }

    public override Type SettingsType => typeof(LoungeModModuleSettings);
    public static LoungeModModuleSettings Settings => (LoungeModModuleSettings) Instance._Settings;

    public override Type SessionType => typeof(LoungeModModuleSession);
    public static LoungeModModuleSession Session => (LoungeModModuleSession) Instance._Session;

    public override Type SaveDataType => typeof(LoungeModModuleSaveData);
    public static LoungeModModuleSaveData SaveData => (LoungeModModuleSaveData) Instance._SaveData;

    public LoungeModModule() {
        Instance = this;
#if DEBUG
        // debug builds use verbose logging
        Logger.SetLogLevel(nameof(LoungeModModule), LogLevel.Verbose);
#else
        // release builds use info logging to reduce spam in log files
        Logger.SetLogLevel(nameof(LoungeModModule), LogLevel.Info);
#endif
    }

    public Session oldSession = null;

    public override void Load()
    {
        Everest.Events.Level.OnCreatePauseMenuButtons += onCreatePauseMenuButtons;
    }

    private void onCreatePauseMenuButtons(Level level, TextMenu menu, bool minimal)
    {
        int retryIndex = menu.Items.FindIndex(item =>
            item.GetType() == typeof(TextMenu.Button) && ((TextMenu.Button)item).Label == Dialog.Clean("menu_pause_retry"));

        if (retryIndex != -1)
        {
            menu.Insert(++retryIndex, new TextMenu.Button(Dialog.Clean("MODOPTIONS_LOUNGEMOD_PAUSEMENU_BUTTON"))
            {
                OnPressed = () =>
                {
                    menu.OnCancel();
                    if (oldSession == null)
                    {
                        teleportToMap(level);
                    }
                    else
                    {
                        teleportFromMap(level);
                    }
                },
                Disabled = false,
            });
        }

        int saveIndex = menu.Items.FindIndex(item =>
            item.GetType() == typeof(TextMenu.Button) && ((TextMenu.Button)item).Label == Dialog.Clean("menu_pause_savequit"));
        int returnIndex = menu.Items.FindIndex(item =>
            item.GetType() == typeof(TextMenu.Button) && ((TextMenu.Button)item).Label == Dialog.Clean("menu_pause_return"));
        if (saveIndex != -1)
        {
            menu.Items[saveIndex].Disabled = (oldSession != null) ? true : false;
        }
        if (returnIndex != -1)
        {
           menu.Items[returnIndex].Disabled = (oldSession != null) ? true : false; 
        }
    }

    private void teleportToMap(Level level) {
        string mapSID = "LoungeMod_loaded_map";
        level.DoScreenWipe(false, () =>
        {
            oldSession = level.Session;
            Session session = new Session(AreaData.Get(mapSID).ToKey());
            session.FirstLevel = false;
            session.StartedFromBeginning = false;
            session.Level = session.MapData.StartLevel().Name;
            session.RespawnPoint = session.MapData.StartLevel().DefaultSpawn;
            LevelEnter.Go(session, false);
        });
    }

    private void teleportFromMap(Level level) {
        level.DoScreenWipe(false, () =>
        {
            LevelEnter.Go(oldSession, false);
            oldSession = null;
        });
    }

    public override void Unload()
    {
        Everest.Events.Level.OnCreatePauseMenuButtons -= onCreatePauseMenuButtons;
    }
}