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

public class MainMenuEngine : MonoBehaviour
{
    public GameObject hudGO;
    public GameObject joystickGO;
    public GameObject yolkAGO;
    public GameObject yolkBGO;
    public TMPro.TextMeshProUGUI versionText;

    public TMPro.TMP_Dropdown qualityDropdown;
    public TMPro.TMP_Dropdown resolutionDropdown;
    public TMPro.TMP_Dropdown fullscreenDropdown;
    public List<RenderPipelineAsset> renderPipelines = new List<RenderPipelineAsset>();

    public BackgroundMusicManager currentBGMManager;
    public MenuAudioManager currentMenuAudioManager;

    public float joystickJiggleSpeed;

    public float flashFrequencyTime;
    private TimerHelper _flashTimer;

    private MeshRenderer _meshRenderer;
    private Color _defaultEmissionColor;

    private GameObject _lastControlSelected;

    private void Awake()
    {
        GameManager.Instance.currentGameState = GameState.MAINMENU;
    }

    // Start is called before the first frame update
    void Start()
    {
        // If the BGM manager is present, queue up and play the given track index
        if (currentBGMManager)
        {
            currentBGMManager.StartAudioQueueAndPlay(0);
        }

        _flashTimer = new TimerHelper(flashFrequencyTime);
        _meshRenderer = hudGO.GetComponent<MeshRenderer>();
        _defaultEmissionColor = _meshRenderer.materials[0].GetColor("_EmissionColor");

        _lastControlSelected = EventSystem.current.firstSelectedGameObject;
        versionText.text = versionText.text.Replace("{versionNo}", GameManager.Instance.CurrentVersion);
    }

    public void SetupVolumeOptions()
    {
        // Gets the volume settings from the player profile and sets it in the game
        float currentMasterVol = PlayerPrefs.GetFloat("currentMasterVol");
        GameObject masterVolSliderGo = GameObject.Find("MainVolSlider");

        float currentMusicVol = PlayerPrefs.GetFloat("currentMusicVol");
        GameObject musicVolSliderGo = GameObject.Find("MusicVolSlider");

        float currentSFXVol = PlayerPrefs.GetFloat("currentSFXVol");
        GameObject SFXVolSliderGo = GameObject.Find("SfxVolSlider");

        masterVolSliderGo.GetComponent<Slider>().value = currentMasterVol;
        musicVolSliderGo.GetComponent<Slider>().value = currentMusicVol;
        SFXVolSliderGo.GetComponent<Slider>().value = currentSFXVol;

        qualityDropdown.value = QualitySettings.GetQualityLevel();

        int selectedResolution = 0;
        string resolutionString = Screen.width.ToString() + " X " + Screen.height.ToString();
        switch(resolutionString)
        {
            case "1280 X 720":
                selectedResolution = 1;
                break;
            case "1280 X 800":
                selectedResolution = 2;
                break;
            case "1366 X 768":
                selectedResolution = 3;
                break;
            case "1440 X 900":
                selectedResolution = 4;
                break;
            case "1680 X 1050":
                selectedResolution = 5;
                break;
            case "1920 X 1080":
                selectedResolution = 6;
                break;
            case "2560 X 1440":
                selectedResolution = 7;
                break;
            case "3840 X 2160":
                selectedResolution = 8;
                break;
            default:
                selectedResolution = 0;
                break;
        }

        resolutionDropdown.value = selectedResolution;

        int fullscreenModeId = 0;
        switch (Screen.fullScreenMode)
        {            
            case FullScreenMode.ExclusiveFullScreen:
                fullscreenModeId = 0;
                break;
            case FullScreenMode.Windowed:
                fullscreenModeId = 2;
                break;
            default:
            case FullScreenMode.FullScreenWindow:
                fullscreenModeId = 1;
                break;
            
                
        }

        fullscreenDropdown.value = fullscreenModeId;
    }

    public void SaveOptionChanges()
    {
        QualitySettings.SetQualityLevel(qualityDropdown.value);
        QualitySettings.renderPipeline = renderPipelines[qualityDropdown.value];

        int resolutionWidth = Screen.width;
        int resolutionHeight = Screen.height;
        switch(resolutionDropdown.value)
        {
            case 1:
                resolutionWidth = 1280;
                resolutionHeight = 720;
                break;
            case 2:
                resolutionWidth = 1280;
                resolutionHeight = 800;
                break;
            case 3:
                resolutionWidth = 1366;
                resolutionHeight = 768;
                break;
            case 4:
                resolutionWidth = 1440;
                resolutionHeight = 900;
                break;
            case 5:
                resolutionWidth = 1680;
                resolutionHeight = 1050;
                break;
            case 6:
                resolutionWidth = 1920;
                resolutionHeight = 1080;
                break;
            case 7:
                resolutionWidth = 2560;
                resolutionHeight = 1440;
                break;
            case 8:
                resolutionWidth = 3840;
                resolutionHeight = 2160;
                break;
            default:
            case 0:                
                break;
        }

        FullScreenMode newFullScreenMode = Screen.fullScreenMode;
        switch(fullscreenDropdown.value)
        {
            case 0:
                newFullScreenMode = FullScreenMode.ExclusiveFullScreen;
                break;
            case 2:
                newFullScreenMode = FullScreenMode.Windowed;
                break;
            default:
            case 1:
                newFullScreenMode = FullScreenMode.FullScreenWindow;
                break;
        }

        Screen.SetResolution(resolutionWidth, resolutionHeight, newFullScreenMode);
    }

    public void PlayMenuClick()
    {
        if (currentMenuAudioManager)
        {
            currentMenuAudioManager.PlayMenuClick();
        }
    }

    public void StartGame()
    {
        // Play the menu click sound if the audio manager is present
        if (currentMenuAudioManager)
        {
            currentMenuAudioManager.PlayMenuClick();
        }
        SceneManager.LoadSceneAsync("Rules");
    }

    public void Quit()
    {
        // Play the menu click sound if the audio manager is present
        if (currentMenuAudioManager)
        {
            currentMenuAudioManager.PlayMenuClick();
        }

#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
             Application.Quit();
#endif
    }

    public void SetMasterVolume(float value)
    {
        // Converts the master volume into decibels and stores it in the player profile
        GameManager.Instance.currentAudioMixer.SetFloat("masterVol", SharedMethods.ConvertToDecibels(value));
        PlayerPrefs.SetFloat("currentMasterVol", value);
    }

    public void SetMusicVolume(float value)
    {
        // Converts the music volume into decibels and stores it in the player profile
        GameManager.Instance.currentAudioMixer.SetFloat("musicVol", SharedMethods.ConvertToDecibels(value));
        PlayerPrefs.SetFloat("currentMusicVol", value);
    }

    public void SetSFXVolume(float value)
    {
        // Converts the sfx volume into decibels and stores it in the player profile
        GameManager.Instance.currentAudioMixer.SetFloat("sfxVol", SharedMethods.ConvertToDecibels(value));
        PlayerPrefs.SetFloat("currentSFXVol", value);
    }

    // Update is called once per frame
    void Update()
    {
        if (_flashTimer.HasTicked(Time.deltaTime))
        {
            float randomNo = Random.Range(0.0f, 1.0f);
            _meshRenderer.materials[0].SetColor("_EmissionColor", Color.Lerp(Color.black, _defaultEmissionColor, randomNo));
        }

        float horzIn = Input.GetAxis("Horizontal");
        float vertIn = Input.GetAxis("Vertical");
        float horzLRot = -horzIn * joystickJiggleSpeed;
        float vertLRot = -45.0f + -vertIn * joystickJiggleSpeed;
        joystickGO.transform.eulerAngles = new Vector3(vertLRot, 0.0f, horzLRot);

        if (horzIn != 0 || vertIn != 0)
        {
            if (EventSystem.current.currentSelectedGameObject == null)
            {
                EventSystem.current.SetSelectedGameObject(_lastControlSelected);
            } 
            else
            {
                _lastControlSelected = EventSystem.current.currentSelectedGameObject;
            }
        }

        float horzRRot = -25 + -Input.GetAxis("Mouse X") * joystickJiggleSpeed;
        float vertRRot = -25 + -Input.GetAxis("Mouse Y") * joystickJiggleSpeed;
        yolkAGO.transform.eulerAngles = new Vector3(vertRRot, 0.0f, 0.0f);
        yolkBGO.transform.eulerAngles = new Vector3(horzRRot, 0.0f, 0.0f);
    }
}
