using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    [Header("Starting cards")]
    [SerializeField] private GameObject startingCards;
    [SerializeField] private GameObject buildingsParent;

    [Header("In-game day lenght")]
    [SerializeField] private float dayLenghtInMinutes;

    [Header("UI")]
    [SerializeField] private TextMeshProUGUI timeDisplay;
    [SerializeField] private TextMeshProUGUI dayDisplay;
    [SerializeField] private Toggle pause;
    [SerializeField] private Toggle normal;
    [SerializeField] private Toggle speedX2;
    [SerializeField] private Toggle speedX3;

    private Image pauseImage;
    private Image normalImage;
    private Image speedX2Image;
    private Image speedX3Image;
    private Toggle lastToggle;

    private int currentDay = 0;
    private float InGameDayInSeconds => dayLenghtInMinutes * 60;
    private float dayTimer = 0;

    private bool gameIsOn = false;
    public bool GameIsOn { get { return gameIsOn; }}

    private bool pauseGame = true;
    public bool PauseGame { get { return pauseGame; }}

    private float gameSpeed = 0;
    public float GameSpeed { 
        get { return gameIsOn && !pauseGame ? gameSpeed * Time.deltaTime : 0; } 
    }

    public bool CreativeMoveOn { get; set; }

    public static GameManager Instance;
    private void Awake()
    {
        if (Instance == null) Instance = this;
        else Destroy(gameObject);

        dayTimer = InGameDayInSeconds;

        timeDisplay.text = TimerToTimeStringMinute();
        dayDisplay.text = currentDay.ToString();

        #region Toggles
        pauseImage = pause.GetComponent<Image>();
        normalImage = normal.GetComponent<Image>();
        speedX2Image = speedX2.GetComponent<Image>();
        speedX3Image = speedX3.GetComponent<Image>();

        lastToggle = pause;
        pause.onValueChanged.AddListener((bool isOn) => {
            if (isOn)
            {
                //toggleGroup.SetAllTogglesOff();
                if (gameSpeed == 0)
                {
                    lastToggle.isOn = true;
                    pauseImage.color = Color.gray;
                }
                else
                {
                    gameSpeed = 0;
                    pauseImage.color = Color.white;
                }
            }else pauseImage.color = Color.gray;
        });

        normal.onValueChanged.AddListener((bool isOn) =>
        {
            if (isOn)
            {
                gameSpeed = 1;
                normalImage.color = Color.white;
            }
            else
            {
                lastToggle = normal;
                normalImage.color = Color.gray;
            }
        });

        speedX2.onValueChanged.AddListener((bool isOn) =>
        {
            if (isOn)
            {
                gameSpeed = 2;
                speedX2Image.color = Color.white;
            }
            else
            {
                lastToggle = speedX2;
                speedX2Image.color = Color.gray;
            }
        });

        speedX3.onValueChanged.AddListener((bool isOn) =>
        {
            if (isOn)
            {
                gameSpeed = 3;
                speedX3Image.color = Color.white;
            }
            else
            {
                lastToggle = speedX3;
                speedX3Image.color = Color.gray;
            }
        });
        #endregion

        Events.OnPlaceCard += OnPlaceCard;

        Events.OnDayStart += OnDayStart;
        Events.OnGameStart += OnGameStart;
        Events.OnGameEnd += OnGameEnd;
    }

    private void OnDestroy()
    {
        Events.OnPlaceCard -= OnPlaceCard;

        Events.OnDayStart -= OnDayStart;
        Events.OnGameStart -= OnGameStart;
        Events.OnGameEnd -= OnGameEnd;
    }

    private void Start()
    {
        foreach (var card in startingCards.GetComponentsInChildren<Card>())
        {
            OnPlaceCard(card);
            Events.AddCard(card);
        }
    }

    private string TimerToTimeStringMinute()
    {
        int min = (int)(dayTimer / 60);
        int sec = (int)(dayTimer % 60);
        return min.ToString().PadLeft(2, '0') + ":" + sec.ToString().PadLeft(2, '0');
    }

    private void Update()
    {
        if (gameIsOn)
        {
            #region Speed toggles keyboard controls
            if (Input.GetKeyDown(KeyCode.Space))
            {
                pause.isOn = !pause.isOn;
            }
            else if (Input.GetKeyDown(KeyCode.Alpha1))
            {
                normal.isOn = true;
            }
            else if (Input.GetKeyDown(KeyCode.Alpha2))
            {
                speedX2.isOn = true;
            }
            else if (Input.GetKeyDown(KeyCode.Alpha3))
            {
                speedX3.isOn = true;
            }
            #endregion

            dayTimer -= GameSpeed;

            timeDisplay.text = TimerToTimeStringMinute();

            if (dayTimer <= 0)
            {
                if (!CreativeMoveOn)
                    PeopleManager.Instance.CalculateMissingStats();
                Events.DayEnd();
                pauseGame = true;
            }
        }
    }

    private void OnPlaceCard(Card card)
    {
        CardHolderBuilding cardHolder = Instantiate(
            card.cardData.BuildingPrefab, 
            card.transform.position, 
            Quaternion.identity, 
            buildingsParent.transform);
        card.PlaceCard(cardHolder.GetComponentInChildren<CardHoldArea>());

        MapManager.Instance.NewBuildingPlaced(
            cardHolder.transform.position,
            cardHolder.BuildingData
            );
        MapManager.Instance.BuildingBuilt(
            cardHolder.transform.position,
            cardHolder.BuildingData);
    }

    private void OnDayStart()
    {
        dayTimer = InGameDayInSeconds;
        currentDay++;
        dayDisplay.text = currentDay.ToString();
        pauseGame = false;
    }

    private void OnGameEnd()
    {
        gameIsOn = false;
    }

    private void OnGameStart()
    {
        gameIsOn = true;
        pauseGame = false;
    }
}
