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

public enum GameMode
{
    SinglePlayer,
    LocalMultiplayer,
    CashSystem
}

public class GameManager : MonoBehaviour
{ //Game Mode
    public GameMode currentGameMode;

    //Single Player
    public GameObject inScenePlayer;

    //Local Multiplayer
    public GameObject playerPrefab;
    public GameObject homeScreen;
    public GameObject splashScreen;
    public int numberOfPlayers;

    public Transform spawnRingCenter;
    public float spawnRingRadius;

    //Spawned Players
    
    private bool isPaused;
    

    public static GameManager Instance;
    public ModeSelection modeSelection;
    public WaitingSceneManager waitingSceneManager;

    private int enemiesDefeated = 0;

    public AudioSource audioSource;
    public AudioSource sfxSource;

    ///this should carry the value of the selected players from the modeselection script and make it available in another scene(game scene)
    public Dictionary<string, PlayerInfo> selectedPlayerDevice;

    [SerializeField]
    private Slider progressBar;

    public RawImage rawImage;
    public VideoPlayer videoPlayer;
    private bool isVideoFinished = false;

    public event Action SplashSequenceCompleted;

    public GameObject loadingUI;  // Reference to the Loading UI Canvas

    // private GameSettings gameSettings;
    // void OnEnable(){
    //     //If Key is present, then load
    //     if (PlayerPrefs.HasKey(GameSettingsKey))
    //     {
    //         gameSettings = LoadGameSettings(); //Load
    //     }
    //     // else{
    //     //     DefaultSettings(); //Set Volume and Controls Settings
    //     //     // SaveGameSettings();
    //     // }
    // }

    private GameSettings gameSettings;
    void LoadAudioSetings(){
        if (PlayerPrefs.HasKey(GameSettingsKey))
        {
            gameSettings = LoadGameSettings(); //Load
        }
        else
        {
            gameSettings = new GameSettings(); // Create default settings if none exist
        }
    }


    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return; // prevent duplicate initialization
        }

        Instance = this;
        DontDestroyOnLoad(gameObject);

        if (sfxSource == null)
        {
            sfxSource = gameObject.AddComponent<AudioSource>();
            sfxSource.playOnAwake = false;
        }

        if (selectedPlayerDevice == null)
            selectedPlayerDevice = new Dictionary<string, PlayerInfo>();

        audioSource = GetComponent<AudioSource>();
    }



    void Start()
    {

        isPaused = false;

        //SetupBasedOnGameState();
        //SetupUI();
        

        // Set the video player's target texture to the raw image's texture
        videoPlayer.targetTexture = new RenderTexture(Screen.width, Screen.height, 24);
        rawImage.texture = videoPlayer.targetTexture;

        // Record when splash started for minimum duration check
        splashStartTime = Time.realtimeSinceStartup;
        
        // Subscribe to the videoPlayer's completion event
        videoPlayer.loopPointReached += OnVideoFinished;
        
    }


    //BG Music
    public void PlayBackgroundMusic()
    {
        //audio play
        LoadAudioSetings();
        Debug.Log($"BG MUSIC PLAYING {gameSettings.GameplayVolume_value}");
        audioSource.volume = gameSettings.GameplayVolume_value;
        audioSource.Play();
    }


    //UI click
    public void PlaySound(AudioClip sfxClip)
    {
        if (sfxClip == null)
        {
            Debug.LogWarning("Attempted to play null audio clip");
            return;
        }

        if (sfxSource == null)
        {
            Debug.LogWarning("sfxSource is null, attempting to recreate");
            sfxSource = gameObject.AddComponent<AudioSource>();
            sfxSource.playOnAwake = false;
        }

        LoadAudioSetings();
        sfxSource.clip = sfxClip;
        sfxSource.volume = gameSettings != null ? gameSettings.UIVolume_value : 1f;
        sfxSource.Play();
    }


    public void ActivateHomeScreen()
    {
        // Perform actions to activate the home screen here
        homeScreen.SetActive(true);
        
    }

    // Minimum time (seconds) the splash should display before transitioning
    private float splashStartTime;
    private const float MIN_SPLASH_DURATION = 2.0f; // At least 2 seconds
    
    // Method called when the video finishes playing
    private void OnVideoFinished(VideoPlayer player)
    {
        // Set the flag to true to indicate that the video has finished playing
        if (isVideoFinished)
        {
            return;
        }

        // Check if the video actually played for a reasonable duration
        float timeSinceSplashStart = Time.realtimeSinceStartup - splashStartTime;
        double videoLength = player != null && player.length > 0 ? player.length : 0;
        
        Debug.Log($"[GameManager] loopPointReached triggered. Time since start: {timeSinceSplashStart:F2}s, Video length: {videoLength:F2}s, IsPlaying: {player?.isPlaying}");
        
        // If the event fired too quickly (video didn't actually play), wait for it
        if (timeSinceSplashStart < MIN_SPLASH_DURATION && timeSinceSplashStart < videoLength * 0.5f)
        {
            Debug.LogWarning($"[GameManager] Video finished too quickly ({timeSinceSplashStart:F2}s). Starting fallback wait...");
            StartCoroutine(WaitForMinimumSplashDuration());
            return;
        }

        isVideoFinished = true;

        Debug.Log("[GameManager] Splash video finished. Starting scene load coroutine to avoid blocking main thread.");

        // Start coroutine to avoid blocking the VideoPlayer callback thread
        StartCoroutine(LoadMenuAfterSplash());
    }
    
    private System.Collections.IEnumerator WaitForMinimumSplashDuration()
    {
        // Wait until minimum duration has passed
        float remainingTime = MIN_SPLASH_DURATION - (Time.realtimeSinceStartup - splashStartTime);
        if (remainingTime > 0)
        {
            Debug.Log($"[GameManager] Waiting {remainingTime:F2}s for minimum splash duration...");
            yield return new WaitForSeconds(remainingTime);
        }
        
        if (!isVideoFinished)
        {
            isVideoFinished = true;
            Debug.Log("[GameManager] Minimum splash duration reached. Starting scene load.");
            StartCoroutine(LoadMenuAfterSplash());
        }
    }

    private System.Collections.IEnumerator LoadMenuAfterSplash()
    {
        ShowLoadingUI();

        // Invoke the event - GameInitialize will handle scene loading if subscribed
        // This prevents duplicate scene load attempts
        bool hasSubscribers = SplashSequenceCompleted != null;
        SplashSequenceCompleted?.Invoke();

        // Wait one frame to ensure UI updates before potentially heavy operations
        yield return null;

        // Only load scene directly if no subscribers handled it
        // (GameInitialize subscribes when forceMenuDuringDevelopment is true)
        if (!hasSubscribers)
        {
            const string forcedScene = "MenuScene";
            Debug.Log("[GameManager] Loading '" + forcedScene + "' via LoadingScreen (no external subscribers).");
            LoadSceneWithLoading(forcedScene);
        }
        else
        {
            Debug.Log("[GameManager] Splash finished - scene loading handled by subscriber.");
        }
    }

    private void ActivateLoadingBar()
    {
        // Show the loading bar or perform any other loading-related actions here
        //SceneManager.LoadScene("MenuScene", LoadSceneMode.Single);


        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    public void OnSceneLoaded(Scene scene, LoadSceneMode mode){
        SceneManager.sceneLoaded -= OnSceneLoaded; // Unregister event handler

        if (scene.name != "MenuScene")
        {
            return;
        }

        // Debug.Log("XT Loading Bar");

        //Find GameObject with name "UI"
        GameObject uiObject = GameObject.Find("UI");
        if (uiObject != null){
            /*foreach (Transform child in uiObject.transform){
                if ((child.name != "ModeSelection")){
                    child.gameObject.SetActive(false);
                }
            }*/


            //Check if Announcements have been shown or not, if shown, go to Loading_Screen UI, but if not yet shown, then go to Announcements UI
            // Check if the "announcement" key exists in PlayerPrefs

            // Get the value of the "announcement" key
            string announcementValue = PlayerPrefs.GetString("announcementStatus");

            // Check if the value is "0", Announcements have not happened
            if (announcementValue == "0"){
                GameObject announcements_to_show = uiObject.transform.Find("Announcements")?.gameObject;

                if (announcements_to_show != null){
                    announcements_to_show.SetActive(true); //When the Menu scene is activated, show this UI

                }else{
                    Debug.Log("No Announcements screen");
                }
            }
            else{ //Announcements already happened

                //LoadingScreen loadingscript = GetComponent<LoadingScreen>();
                //ActivateHomeScreen();
                //GameManager.Instance.gameObject.GetComponent<LoadingScreen>().UI_to_show_AfterLoading(2, "Home");

            }    
            
        }
        else{
            Debug.LogError("UI GameObject not found in MenuScene!");
        }
    }

    public void IncrementEnemiesDefeated()
    {
        enemiesDefeated++;
    }

    public int GetEnemiesDefeated()
    {
        return enemiesDefeated;
    }

    

    void SetupLocalMultiplayer()
    {

        if (inScenePlayer == true)
        {
            Destroy(inScenePlayer);
        }
    }

    public void HideLoadingUI()
    {
        loadingUI.SetActive(false);
    }


    public bool HasSplashFinished => isVideoFinished;

    public void ShowLoadingUI()
    {
        if (loadingUI == null)
        {
            if (gameObject.transform.childCount > 0)
            {
                loadingUI = gameObject.transform.GetChild(0).gameObject;
            }
            else
            {
                Debug.LogError("ShowLoadingUI: No child GameObject found. Please ensure the hierarchy is set up correctly.");
                return;
            }
        }
        loadingUI.SetActive(true);
    }

    public void LoadSceneWithLoading(string sceneName)
    {
        if (string.IsNullOrEmpty(sceneName))
        {
            Debug.LogError("LoadSceneWithLoading: sceneName is null or empty");
            return;
        }

        var loadingScreen = GetComponentInChildren<LoadingScreen>(true);
        if (loadingScreen != null)
        {
            loadingScreen.UI_to_show_AfterLoading(1, sceneName);
            ShowLoadingUI();
        }
        else
        {
            Debug.LogWarning("LoadSceneWithLoading: LoadingScreen component not found. Falling back to direct scene load.");
            SceneManager.LoadScene(sceneName, LoadSceneMode.Single);
        }
    }


    //Saving and Loading Game Settings
    #region
    private const string GameSettingsKey = "GameSettings";

        public static void SaveGameSettings(GameSettings settings){
            string json = JsonUtility.ToJson(settings);
            PlayerPrefs.SetString(GameSettingsKey, json);
            PlayerPrefs.Save();
        }

        public static GameSettings LoadGameSettings(){
            if (PlayerPrefs.HasKey(GameSettingsKey))
            {
                string json = PlayerPrefs.GetString(GameSettingsKey);
                return JsonUtility.FromJson<GameSettings>(json);
            }
            return new GameSettings(); // Return default settings if none are saved
        }

    #endregion

}
