using System;
using UnityEngine;
using Object = UnityEngine.Object;
using System.Collections.Generic;
using Abilities;
using TMPro;
using Unity.VisualScripting;

public enum GameState
{
    RollDice,
    PickRoomOne,
    PickRoomTwo,
    PickDiceOne,
    PickDiceTwo,
}
public class GameManager : MonoBehaviour
{
    [SerializeField] public static GameState State;
    [SerializeField] private GameObject rooms;
    [SerializeField] private DiceRoller diceRoller;
    [SerializeField] private PassManager passManager;
    [SerializeField] private Player player;

    private DicePair _dicePairOne = new();
    private DicePair _dicePairTwo = new();
    public static event Action<GameState> StateChanged;
    public static event Action<DicePair> DiceSelected;
    public static event Action DiceUnselected;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        diceRoller.diceRolled += DiceRolled;
        passManager.PassRequested += PassRequested;
        foreach (Transform roomTransform in rooms.transform)
        {
            roomTransform.gameObject.GetComponent<Room>().RoomExploredByDice += HandleRoomExploredByDice;
        }
        foreach (Transform diceTransform in diceRoller.dice.transform)
        {
            diceTransform.gameObject.GetComponent<Die>().DieSelected += HandleDieSelected;
            diceTransform.gameObject.GetComponent<Die>().DieUnselected += HandleDieUnselected;
        }
        StartNewTurn();
    }
    
    private void ChangeState(GameState stateToChangeTo) {
        if (State != stateToChangeTo)
        {
            State = stateToChangeTo;
            StateChanged?.Invoke(State);
        }
    }

    private void StartNewTurn()
    {
        ChangeState(GameState.RollDice);
        diceRoller.Enable();
        diceRoller.ResetDice();
        _dicePairOne = new DicePair();
        _dicePairTwo = new DicePair();
    }

    void HandleRoomExploredByDice(object sender, Room room) {
        if (State == GameState.PickRoomOne)
        {
            ChangeState(GameState.PickDiceTwo);
        }
        else
        {
            StartNewTurn();
        }
    }

    private void HandleDieSelected(Die die) {
        switch (State)
        {
            case GameState.PickDiceOne:
                _dicePairOne.SelectDie(die);
                if (_dicePairOne.AreBothDiceSelected())
                {
                    ChangeState(GameState.PickRoomOne);
                    DiceSelected?.Invoke(_dicePairOne);
                }
                break;
            case GameState.PickDiceTwo:
                _dicePairTwo.SelectDie(die);
                if (_dicePairTwo.AreBothDiceSelected())
                {
                    ChangeState(GameState.PickRoomTwo);
                    DiceSelected?.Invoke(_dicePairTwo);
                }
                break;
            default:
                return;
        }
    }

    private void HandleDieUnselected(Die die) {
        switch (State)
        {
            case GameState.PickDiceOne:
            case GameState.PickRoomOne:
                if (State == GameState.PickRoomOne)
                {
                    ChangeState(GameState.PickDiceOne);
                }
                _dicePairOne.UnselectDie(die);
                DiceUnselected?.Invoke();
                break;
            case GameState.PickDiceTwo:
            case GameState.PickRoomTwo:
                if (State == GameState.PickRoomTwo)
                {
                    ChangeState(GameState.PickDiceTwo);
                }
                _dicePairTwo.UnselectDie(die);
                DiceUnselected?.Invoke();
                break;
        }
    }

    private void PassTurn() {
        player.TakeDamage(1);
        StartNewTurn();
    }

    private void DiceRolled(object sender, EventArgs e)
    {
        if (State == GameState.RollDice)
        {
            diceRoller.Disable();
            ChangeState(GameState.PickDiceOne);
        }
    }

    private void PassRequested(object sender, EventArgs e) {
        switch (State)
        {
            case GameState.PickDiceOne:
            case GameState.PickDiceTwo:
            case GameState.PickRoomOne:
            case GameState.PickRoomTwo:
                PassTurn();
                break;
            default:
                return;
        }
    }
}
