using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//using UnityEngine.Analytics;
using UnityEngine.SceneManagement;
using Gamelogic.Grids2;

public class GameController : MonoBehaviour
{
    public Transform PlayerPrefab;

    public static int CurrentDepth { get { return Instance.LevelNum; } }
    public static GameController Instance;

    public string DEBUG;

    private bool levelIsLoading = false;
    private float levelLoadingUntil = 0;

    public bool IsGameShuttingDown = false;

    public bool DebugKeysAllowed = false;

    private enum GameState
    {
        MenuTitleScreen,
        LevelScreen,
        Running,
        SummaryScreen,
        GameOver,
        BeatGame
    }
    private GameState state;
    private float lastSwitchTime;

    public int LevelNum = 0;
    private bool LevelFinished = false;
    private bool startLevel = false;
    private bool playerLost = false;

    private float gameClockStart;
    private bool onTitleScreen = true; // TODO unfortunately i bundeld some init in the title screen that's needed for restarts, but this is in need of a refactor

    void Awake()
    {
        Instance = this;
        DontDestroyOnLoad(transform.gameObject);
    }

    void Start()
    {
        EnterState(GameState.MenuTitleScreen);
    }

    void OnApplicationQuit()
    {
        Debug.Log("GameController.OnApplicationQuit");
        IsGameShuttingDown = true;
    }

    public bool isGameRunning()
    {
        return (levelLoadingUntil < Time.time) && state == GameState.Running;
    }

    public bool isInLevelScreen()
    {
        return state == GameState.LevelScreen;
    }

    public bool isInPlayScreen()
    {
        return state == GameState.Running;
    }

    public void Descend()
    {
        Debug.Log("GameController Descend");
        LevelFinished = true;
    }

    public void LoseGame()
    {
        playerLost = true;
    }

    public void StartLevel()
    {
        startLevel = true;
    }

    public void FoundTheAmulet()
    {
        EnterState(GameState.BeatGame);
    }

    public void SkipToLevel(int l)
    {
        LevelNum = l;
        EnterState(GameState.LevelScreen);
    }

    private bool CheckDebugKeys()
    {
        if (!DebugKeysAllowed)
            return false;

        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            SkipToLevel(1);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            SkipToLevel(2);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            SkipToLevel(3);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            SkipToLevel(4);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            SkipToLevel(5);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha6))
        {
            SkipToLevel(6);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha7))
        {
            SkipToLevel(7);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha8))
        {
            SkipToLevel(8);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha9))
        {
            SkipToLevel(9);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha0))
        {
            SkipToLevel(10);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Minus))
        {
            SkipToLevel(11);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Equals))
        {
            SkipToLevel(12);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Backspace))
        {
            SkipToLevel(13);
            return true;
        }
        else if (Input.GetKeyDown(KeyCode.Home))
        {
            SkipToLevel(14);
            return true;
        }

        return false;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
            Application.Quit();

        /* Analytics
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Analytics.CustomEvent("QuitGame", new Dictionary<string, object>
                          {
                            { "LevelNum", LevelNum },
                            { "Gametime", Time.realtimeSinceStartup}
                          });

            Application.Quit();
        }
        */

        if (CheckDebugKeys())
            return;


        switch (state)
        {
            case GameState.MenuTitleScreen:
                if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space) || !onTitleScreen)
                {
                    onTitleScreen = false;
                    LevelNum = 1;
                    EnterState(GameState.LevelScreen);
                }
                break;

            case GameState.LevelScreen:
                if (true)//(startLevel)
                {
                    levelLoadingUntil = Time.time + 5f;
                    Debug.Log("Loading Level " + LevelNum);
                    SceneManager.LoadScene("PlayScene");
                    LevelFinished = false;
                    playerLost = false;
                    EnterState(GameState.Running);
                }
                break;

            case GameState.Running:
                if (playerLost)
                {
                    Debug.Log("GameController: player lost");
                    /*
                         Analytics.CustomEvent("gameOver", new Dictionary<string, object>
                              {
                                { "LevelNum", LevelNum },
                                { "Gametime", Time.realtimeSinceStartup}
                              });
                         */
                    EnterState(GameState.GameOver);
                }
                else
                {
                    if(LevelFinished)
                    {
                        RenderSounds.PlaySound("VictorySong");
                        LevelNum++;
                        EnterState(GameState.LevelScreen);

                        /*
                         Analytics.CustomEvent("levelWon", new Dictionary<string, object>
                              {
                                { "LevelNum", LevelNum },
                                { "Gametime", Time.realtimeSinceStartup}
                              });
                         */
                    }
                }
                break;

            case GameState.GameOver:
                if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
                {
                    EnterState(GameState.MenuTitleScreen);
                }
                break;

            case GameState.BeatGame:
                if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
                {
                    EnterState(GameState.MenuTitleScreen);
                }
                break;

        }
    }

    void OnLevelWasLoaded()
    {
        SetupPlayer();
        levelIsLoading = false;
        if (LevelNum > 1)
            levelLoadingUntil = Time.time + 0.08f;
        else
            levelLoadingUntil = Time.time;
    }

    private void SetupPlayer()
    {
        if (state == GameState.Running)  // when upgrade screen added, this needs to check LevelScreen
        {
            if(LevelNum == 1)
            {
                Debug.Log("Creating Fresh Player for new game");
                CombatLib.ClearPlayer();
                GameObject pgo = GameObject.Find("Player(Clone)");
                if (pgo != null)
                {
                    GameObject.DestroyImmediate(pgo);
                }
                Transform player = GameObject.Instantiate(PlayerPrefab);
                DontDestroyOnLoad(player);

                Actor pactor = player.GetComponent<Actor>();
                GridPoint2 pos = new GridPoint2(9, 1);
                pactor.Location = pos;
                pactor.transform.position = GameMap.Cell[pos].transform.position;
                GameMap.Cell[pos].SetActor(pactor);
            }
            else
            {
                Debug.Log("Placing player");
                GridPoint2 pos = new GridPoint2(9, 1);
                CombatLib.Player.Location = pos;
                CombatLib.Player.transform.position = GameMap.Cell[pos].transform.position;
                GameMap.Cell[pos].SetActor(CombatLib.Player);
            }
 
        }

    }

    private void EnterState(GameState newState)
    {
        lastSwitchTime = Time.time;
        GameState oldState = state;
        state = newState;

        Debug.Log("GameController Entering State " + state + " from " + oldState);

        switch (state)
        {
            case GameState.MenuTitleScreen:
                /*Analytics.CustomEvent("newGame", new Dictionary<string, object>
                            {
                            { "Gametime", Time.realtimeSinceStartup}
                            });
                    */
                break;
            case GameState.LevelScreen:
                //startLevel = false;
                //levelLoadingUntil = Time.time + 5f; // 5 seconds is much longer than level load time
                //SceneManager.LoadScene("UpgradeScreen");
                break;
            case GameState.Running:
                //Player.gameObject.SetActive(true);
                //-Player.localEulerAngles = new Vector3(0,0,0);
                break;
            case GameState.GameOver:
                levelLoadingUntil = Time.time + 5f;
                Debug.Log("Loading GameOver");
                SceneManager.LoadScene("GameOver");
                break;
            case GameState.BeatGame:
                levelLoadingUntil = Time.time + 5f; // 5 seconds is much longer than level load time
                SceneManager.LoadScene("BeatTheGame");
                break;
        }

    }

}
