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

public class CharacterManagerScript : MonoBehaviour {

    [SerializeField] MapScript mapScript;
    [SerializeField] int currentObjectTurn = 0;

    [SerializeField] Button moveButton;
    [SerializeField] Button attackButton;
    [SerializeField] Button defendButton;
    [SerializeField] Button dodgeButton;
    [SerializeField] Button infectButton;
    [SerializeField] Text gameOverText;
    [SerializeField] Text infoText;

    public enum GameState { Playing, PlayerDied, MinionDied, InfectedEnemyWin, KilledEnemyWin};
    public static GameState CurrentState = GameState.Playing;
    bool isGameOver = false;

    void Start ()
    {
        isGameOver = false;
        for (int i = 0; i < MapScript.GetCharacters().Count; i++)
        {
            RandomizeStartPoints(MapScript.GetCharacters()[i]); 
            MapScript.GetCharacters()[i].StartGame();
            int locCurrent = (int)MapScript.GetCharacters()[i].GetCurrentLocation().x +
                (int)(MapScript.GetCharacters()[i].GetCurrentLocation().y * MapScript.GetXTileCount());
            MapScript.GetCharacters()[i].gameObject.transform.position = MapScript.GetTiles()[locCurrent].gameObject.transform.position;

            int locTarget = (int)MapScript.GetCharacters()[i].GetTargetLocation().x +
                (int)(MapScript.GetCharacters()[i].GetTargetLocation().y * MapScript.GetXTileCount());
            MapScript.GetCharacters()[i].GetTargeterObject().transform.position = MapScript.GetTiles()[locTarget].gameObject.transform.position;
        }
        MapScript.GetCharacters()[0].SetCurrentAction(CharacterScript.Action.Move);
        currentObjectTurn = 0;
    }
	
	// Update is called once per frame
	void Update () {
        if (isGameOver == false)
        {
            HandleTurns();
            gameOverText.gameObject.SetActive(false);
        }
        else
        {
            gameOverText.gameObject.SetActive(true);
        }
        HandleGameOver();
    }

    void RandomizeStartPoints(CharacterScript characterToRand)
    {
        bool isSafe = false;
        int X = 0;
        int Y = 0;
        while (!isSafe)
        {

            if (characterToRand.GetCurrentAffiliation() == CharacterScript.Affiliation.Friendly)
            {
                X = Random.Range(0, 3);
                Y = Random.Range(0, 3);
                if (X < 0)
                {
                    X = 0;
                }
                if (Y < 0)
                {
                    Y = 0;
                }
            }
            else if (characterToRand.GetCurrentAffiliation() == CharacterScript.Affiliation.Enemy)
            {
                X = Random.Range(2, MapScript.GetXTileCount());
                Y = Random.Range(2, MapScript.GetYTileCount());
                if(X >= MapScript.GetXTileCount())
                {
                    X = MapScript.GetXTileCount() - 1;
                }
                if (Y >= MapScript.GetYTileCount())
                {
                    Y = MapScript.GetYTileCount() - 1;
                }
            }
            else
            {
                X = Random.Range(0, MapScript.GetXTileCount());
                Y = Random.Range(0, MapScript.GetYTileCount());
            }

            for (int i = 0; i < MapScript.GetCharacters().Count; i++)
            {
                if (MapScript.GetCharacters()[i].GetCurrentLocation() == new Vector2(X, Y))
                {
                    isSafe = false;
                    break;
                }
                else if (MapScript.GetCharacters()[i].GetCurrentLocation() != new Vector2(X, Y))
                {
                    isSafe = true;
                }
            }
        }
        Debug.Log("X: " + X + " Y: " + Y);
        characterToRand.SetCurrentLocation(new Vector2(X, Y));
    }

    void HandleTurns()
    {
        if (currentObjectTurn < MapScript.GetCharacters().Count)
        {
            HandleButtons();
            HandleText();
            MapScript.GetCharacters()[currentObjectTurn].HandleActions();
            //get array location for targter and player
            int locCurrent = (int)MapScript.GetCharacters()[currentObjectTurn].GetCurrentLocation().x +
                (int)(MapScript.GetCharacters()[currentObjectTurn].GetCurrentLocation().y * MapScript.GetXTileCount());
            //Debug.Log("loc: " + locCurrent);
            MapScript.GetCharacters()[currentObjectTurn].gameObject.transform.position = MapScript.GetTiles()[locCurrent].gameObject.transform.position;

            int locTarget = (int)MapScript.GetCharacters()[currentObjectTurn].GetTargetLocation().x +
                (int)(MapScript.GetCharacters()[currentObjectTurn].GetTargetLocation().y * MapScript.GetXTileCount());
            MapScript.GetCharacters()[currentObjectTurn].GetTargeterObject().transform.position = MapScript.GetTiles()[locTarget].gameObject.transform.position;

            //now highlight the tiles the player ahs targeted
            List<int> tiles = new List<int>();
            for (int l = 0; l < MapScript.GetCharacters()[currentObjectTurn].GetLocationsTargeted().Count; l++)
            {
                int tileLoc = (int)MapScript.GetCharacters()[currentObjectTurn].GetLocationsTargeted()[l].x +
                    (int)(MapScript.GetCharacters()[currentObjectTurn].GetLocationsTargeted()[l].y * MapScript.GetXTileCount());
                tiles.Add(tileLoc);

            }
            for (int t = 0; t < MapScript.GetTiles().Count; t++)
            {
                if (tiles.Contains(t))
                {
                    MapScript.GetTiles()[t].SetHighlighted(true);
                }
                else
                {
                    MapScript.GetTiles()[t].SetHighlighted(false);
                }

            }

            if (MapScript.GetCharacters()[currentObjectTurn].GetCurrentAction() == CharacterScript.Action.Wait)
            {
                currentObjectTurn += 1;
                if (currentObjectTurn >= MapScript.GetCharacters().Count)
                {
                    currentObjectTurn = 0;
                }
                MapScript.GetCharacters()[currentObjectTurn].StartTurn();
            }

        }
    }

    void HandleButtons()
    {
        CharacterScript.Action act = MapScript.GetCharacters()[currentObjectTurn].GetCurrentAction();
        if(act == CharacterScript.Action.Wait)
        {

        }
        else if (act == CharacterScript.Action.Move)
        {
            moveButton.Select();
        }
        else if (act == CharacterScript.Action.Attack)
        {
            attackButton.Select();
        }
        else if (act == CharacterScript.Action.Defend)
        {
            defendButton.Select();
        }
        else if (act == CharacterScript.Action.Dodge)
        {
            dodgeButton.Select();
        }
        else if (act == CharacterScript.Action.Infect)
        {
            infectButton.Select();
        }
    }

    void HandleText()
    {
        string dodgeString = "";
        if (MapScript.GetCharacters()[currentObjectTurn].GetDodgePoints() == 0)
        {
            dodgeString = "0%";
        }
        if (MapScript.GetCharacters()[currentObjectTurn].GetDodgePoints() == 1)
        {
            dodgeString = "25%";
        }
        if (MapScript.GetCharacters()[currentObjectTurn].GetDodgePoints() == 2)
        {
            dodgeString = "33%";
        }
        if (MapScript.GetCharacters()[currentObjectTurn].GetDodgePoints() == 3)
        {
            dodgeString = "50%";
        }
        
        infoText.text = MapScript.GetCharacters()[currentObjectTurn].GetCharacterName() + " ap left: " + MapScript.GetCharacters()[currentObjectTurn].GetCurrentActionPoints().ToString() +
            "\r\nDefend Points: " + MapScript.GetCharacters()[currentObjectTurn].GetDefendPoints() +
            "\r\nDodge Chance: " + dodgeString;
    }

    void HandleGameOver()
    {
        for (int i = 0; i < MapScript.GetCharacters().Count; i++)
        {
            if (MapScript.GetCharacters()[i].GetCurrentHealth() <= 0)
            {
                isGameOver = true;
                if (MapScript.GetCharacters()[i].gameObject.tag == "Player")
                {
                    CurrentState = GameState.PlayerDied;
                }
                else if (MapScript.GetCharacters()[i].gameObject.tag == "Enemy")
                {
                    CurrentState = GameState.KilledEnemyWin;
                }
                else if (MapScript.GetCharacters()[i].GetIsInfected())
                {
                    GameObject go = Resources.Load<GameObject>("Resources/Prefabs/Minion");
                    go.transform.position = MapScript.GetCharacters()[i].transform.position;
                    MapScript.GetCharacters()[i].gameObject.SetActive(false);
                    CurrentState = GameState.InfectedEnemyWin;
                }
                StartCoroutine(LoadGameOver());
            }
            else if (MapScript.GetCharacters()[i].GetIsInfected())
            {
                GameObject go = Instantiate(Resources.Load<GameObject>("Prefabs/Minion")) as GameObject;
                go.transform.position = MapScript.GetCharacters()[i].gameObject.transform.position;
                MapScript.GetCharacters()[i].gameObject.SetActive(false);
                CurrentState = GameState.InfectedEnemyWin;
                StartCoroutine(LoadGameOver());
            }
        }
    }

    IEnumerator LoadGameOver()
    {
        //play sound here

        yield return new WaitForSeconds(2.5f);
        SceneManager.LoadScene("GameOverScreen");
    }

}
