using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;

public class UIObjectsContainer : MonoBehaviour {
    static public UIObjectsContainer main;
    public GameObject UIDialogue;
    public ChoiceSelector ChoiceSelector;
    public GameObject Fade;
    public GameObject LetterboxTopBlack;
    public GameObject LetterboxBottomBlack;
    public AudioClip ActionSound;
    public AudioClip MenuMoveSound;
    public AudioClip CancelSound;
    public AudioClip PauseSound;
    public AudioClip ChangeTabSound;
    public EventSystem EventSystem;
    private static float lastSubmitTime = 0.0f;
    public RectTransform ScrollBarFill;
    public RawImage[] GameOverImages;
    public Button[] GameOverButtons;
    public GameObject GameOverMenu;
    public PauseMenu Pause;
    public GameObject Map;
    public static bool showFPS;
    public static bool hiddenCursor = false;
    private bool oldHiddenCurson = false;
    private InputActionReference lc;
    private InputActionReference mc;
    private InputActionReference rc;
    private float currentFPS = 60.0f;
    public UnityEngine.Gradient fpsColor;
    private GUIStyle guiStyle = new GUIStyle();
    public RawImage StartupFade;
    public InputSystemUIInputModule input;
    private int keepScrolling = 0;
    private float scrollingTime = 0.0f;
    public CanvasGroup messageBox;
    public Text messageBoxTitle;
    public Text messageBoxText;
    public RawImage messageBoxImage;
    public GameObject popupPrefab;
    public AudioClip popupSound;
    public CanvasGroup interactionTypeContainer;
    public Text interactionTypeText;
    private bool interactionTypeShown = false;

    void Awake() {
        main = this;
        if (StartupFade != null && Time.timeSinceLevelLoad < 2.0f) {
            StartupFade.gameObject.SetActive(true);
            StartupFade.color = new Color(StartupFade.color.r, StartupFade.color.g, StartupFade.color.b, 1.0f);
        }
        showFPS = PlayerPrefs.GetInt("ShowFPS", 0) == 1;
        hiddenCursor = PlayerPrefs.GetInt("HiddenCursor", 0) == 1;
    }

    void Start() {
        ScriptedScene.CheckForGlobalVariables();
        GlobalVariables.main.UpdateParty();
    }

    void Update() {
        if (StartupFade != null && StartupFade.gameObject.activeInHierarchy && StartupFade.color.a > 0.02 && Time.timeSinceLevelLoad > 0.1f) {
            StartupFade.color = new Color(StartupFade.color.r, StartupFade.color.g, StartupFade.color.b, Mathf.Lerp(StartupFade.color.a, 0.0f, Time.unscaledDeltaTime * 1.0f));
            if (StartupFade.color.a <= 0.02) {
                StartupFade.gameObject.SetActive(false);
            }
        }
        if (hiddenCursor != oldHiddenCurson) {
            if (lc == null) {
                lc = input.leftClick;
            }
            if (mc == null) {
                mc = input.middleClick;
            }
            if (rc == null) {
                rc = input.rightClick;
            }
            if (hiddenCursor) {
                input.leftClick = null;
                input.middleClick = null;
                input.rightClick = null;
            }
            else {
                input.leftClick = lc;
                input.middleClick = mc;
                input.rightClick = rc;
            }
            oldHiddenCurson = hiddenCursor;
        }
        if (GlobalVariables.main.party == null || GlobalVariables.main.party.Count == 0) {
            GlobalVariables.main.UpdateParty();
        }
        if (interactionTypeContainer != null) {
            if (InteractiveTrigger.lastFacingInteractor != null && InteractiveTrigger.lastFacingInteractor.interactable) {
                if (!interactionTypeShown) {
                    interactionTypeText.text = GlobalVariables.Translate(InteractiveTrigger.lastFacingInteractor.interactionName);
                    interactionTypeShown = true;
                }
                if (interactionTypeContainer.alpha < 0.95f) {
                    interactionTypeContainer.alpha = Mathf.Lerp(interactionTypeContainer.alpha, 1.0f, Time.unscaledDeltaTime * 12.0f);
                }
                else if (interactionTypeContainer.alpha != 1.0f) {
                    interactionTypeContainer.alpha = 1.0f;
                }
            }
            else {
                interactionTypeShown = false;
                if (interactionTypeContainer.alpha > 0.05f) {
                    interactionTypeContainer.alpha = Mathf.Lerp(interactionTypeContainer.alpha, 0.0f, Time.unscaledDeltaTime * 12.0f);
                }
                else if (interactionTypeContainer.alpha != 0.0f) {
                    interactionTypeContainer.alpha = 0.0f;
                }
            }
        }
        Entity mainEntity = null;
        if (ThirdPersonController.main != null) {
            mainEntity = ThirdPersonController.main.entity;
        }
        if (mainEntity != null && mainEntity.parameters.currentHP <= 0) {
            Time.timeScale = Mathf.Lerp(Time.timeScale, 0.0f, Time.unscaledDeltaTime * 5.0f);
            if (!UIObjectsContainer.main.GameOverMenu.active) {
                UIObjectsContainer.main.GameOverMenu.SetActive(true);
            }
            if (GameOverImages == null) {
                GameOverImages = UIObjectsContainer.main.GameOverImages;
            }
            if (GameOverButtons == null) {
                GameOverButtons = UIObjectsContainer.main.GameOverButtons;
            }
            for (int i = 0; i < GameOverImages.Length; i++) {
                if (i == 0) {
                    GameOverImages[i].color = new Color(GameOverImages[i].color.r, GameOverImages[i].color.g, GameOverImages[i].color.b, Mathf.Lerp(GameOverImages[i].color.a, 1.0f, Time.unscaledDeltaTime * 2.0f));
                }
                else {
                    GameOverImages[i].color = new Color(GameOverImages[i].color.r, GameOverImages[i].color.g, GameOverImages[i].color.b, Mathf.Lerp(GameOverImages[i].color.a, 0.8f, Time.unscaledDeltaTime * 0.2f));
                }
            }
            bool selectedButton = false;
            if (GameOverImages[0].color.a >= 0.9f) {
                for (int i = 0; i < GameOverButtons.Length; i++) {
                    if (!GameOverButtons[i].gameObject.activeInHierarchy) {
                        GameOverButtons[i].gameObject.SetActive(true);
                        if (i > 0 /*|| !string.IsNullOrEmpty(SaveLoadManager.lastSavegameKey)*/) {
                            GameOverButtons[i].interactable = true;
                            if (!selectedButton) {
                                EventSystem.SetSelectedGameObject(GameOverButtons[i].gameObject);
                                GameOverButtons[i].OnSelect(null);
                                if (i > 0) {
                                    Navigation nav = new Navigation();
                                    GameOverButtons[i].navigation = nav;
                                }
                                selectedButton = true;
                            }
                        }
                        else {
                            GameOverButtons[i].interactable = false;
                        }
                    }
                }
            }
        }
    }

    void OnDestroy() {
        main = null;
    }

    public static void PlayMenuMoveSound() {
        if (main != null && main.MenuMoveSound != null && Time.unscaledTime - lastSubmitTime > 0.1f) {
            ScriptedScene.PlayClipAtPoint(main.MenuMoveSound, Camera.main.transform, true);
        }
    }

    public static void PlayActionSound() {
        if (main != null && main.ActionSound != null && Time.unscaledTime - lastSubmitTime > 0.1f) {
            ScriptedScene.PlayClipAtPoint(main.ActionSound, Camera.main.transform, true);
            lastSubmitTime = Time.unscaledTime;
        }
    }

    public static void PlayCancelSound() {
        if (main != null && main.CancelSound != null && Time.unscaledTime - lastSubmitTime > 0.1f) {
            ScriptedScene.PlayClipAtPoint(main.CancelSound, Camera.main.transform, true);
            lastSubmitTime = Time.unscaledTime;
        }
    }

    public static void PlayPauseSound() {
        if (main != null && main.PauseSound != null) {
            ScriptedScene.PlayClipAtPoint(main.PauseSound, Camera.main.transform, true);
            lastSubmitTime = Time.unscaledTime;
        }
    }

    public static void PlayTabSound() {
        if (main != null && main.ChangeTabSound != null && Time.unscaledTime - lastSubmitTime > 0.1f) {
            ScriptedScene.PlayClipAtPoint(main.ChangeTabSound, Camera.main.transform, true);
            lastSubmitTime = Time.unscaledTime;
        }
    }

    public void OnGUI() {
        if (showFPS && fpsColor!=null) {
            var delta = Time.unscaledDeltaTime;
            float fps = 0.0f;
            if (delta != 0.0) {
                fps = (1 / delta);
            }
            currentFPS = Mathf.Lerp(currentFPS, fps, Time.unscaledDeltaTime * 0.5f);
            guiStyle.normal.textColor = fpsColor.Evaluate(currentFPS / 100.0f);
            guiStyle.fontSize = Mathf.RoundToInt(13 * (Screen.height / 720.0f));
            GUILayout.Label("  " + currentFPS.ToString("#,##0 FPS"), guiStyle);
        }
    }

    public void ChangeScene(string name) {
        SceneEvent.loading = true;
        ScriptedScene.CheckForGlobalVariables();
        GlobalVariables.main.nextLevel = name;
        main.StartCoroutine(main.ChangeScene());
    }

    public static void ChangeScene(string name, SceneEvent.Action a = null) {
        SceneEvent.loading = true;
        ScriptedScene.CheckForCanvas();
        ScriptedScene.CheckForGlobalVariables();
        GlobalVariables.main.nextLevel = name;
        if (a != null) {
            main.StartCoroutine(main.ChangeScene(a));
        }
        else {
            main.StartCoroutine(main.ChangeScene());
        }
    }
    
    public IEnumerator ChangeScene(SceneEvent.Action a = null) {
        ScriptedScene.CheckForCanvas();
        GameObject f = UIObjectsContainer.main.Fade;
        RawImage fi = f.GetComponent<RawImage>();
        float startVolume = MusicManager.main.musicVolume;
        MusicManager.main.musicVolume = 0.0f;
        float time = 0.0f;
        while (time < 3.5f) {
            time += Time.unscaledDeltaTime;
            float alpha = time / 3.5f;
            if (fi.color.a > alpha) {
                alpha = fi.color.a;
            }
            fi.color = new Color(0.0f, 0.0f, 0.0f, alpha);
            yield return null;
        }
        fi.color = new Color(0.0f, 0.0f, 0.0f, 1.0f);
        GlobalVariables gv = GlobalVariables.main;
        if (a != null) {
            foreach (KeyValuePair<string, Entity.Parameters> values in gv.savedEntities) {
                values.Value.replacePosRot = false;
            }
        }
        Cursor.lockState = CursorLockMode.None;
        Time.timeScale = 1.0f;
        PauseMenu.paused = false;
        SceneEvent.ResetStaticVars();
        if (!gv.nextLevel.Equals(gv.objectiveScene)) {
            gv.ResetObjective();
        }
        if (!gv.nextLevel.Equals(gv.saveDeactivationScene)) {
            gv.canSave = true;
        }
        SceneManager.LoadScene(gv.nextLevel);
        if (a != null) {
            a.completed = true;
        }
    }

    public static GameObject ShowPopup(string text, string title = "", AudioClip sound = null) {
        ScriptedScene.CheckForCanvas();
        if (sound != null) {
            ScriptedScene.PlayClipAtPoint(sound, Camera.main.transform.position, true);
        }
        else if (main.popupSound != null) {
            ScriptedScene.PlayClipAtPoint(main.popupSound, Camera.main.transform.position, true);
        }
        GameObject uiMessageGameObject = GameObject.Instantiate(main.popupPrefab, main.transform);
        UIMessage uiMessage = uiMessageGameObject.GetComponent<UIMessage>();
        if (uiMessage != null) {
            uiMessage.title = GlobalVariables.Translate(title).ToUpper();
            uiMessage.text = text;
        }
        return uiMessageGameObject;
    }
}
