using System.Collections.Generic;
using System.Linq;
using UnityEngine;

[System.Serializable]
public class PlayerTileData
{
    public int playerCount;
    public Transform placementTransform;
    public List<PlayerPawn> playerPawns;
}

public class Tile : MonoBehaviour
{
    [SerializeField] private bool isSafeZone = false;
    [SerializeField] private Transform centerPlacementPoint;
    [SerializeField] private Transform[] placementPoints;

    private int lastOccupiedIndex = 0;

    public PlayerPawn PlayerPawn // Change implementation
    {
        get; private set;
    }

    private Queue<Transform> placementQueue = new Queue<Transform>();
    private Dictionary<PlayerTypes, PlayerTileData> playerTypesDict;

    public int PlayerTypesCount => playerTypesDict.Count;
    public bool HasMoreThanOnePlayerType => playerTypesDict.Count > 1;
    public bool IsSafeZone => isSafeZone;

    public Vector3 CenterPlacementPosition => centerPlacementPoint.position;

    public bool ContainsPlayerType(PlayerTypes playerType) => playerTypesDict.ContainsKey(playerType);

    public void Init(int playerTypesCount)
    {
        if (isSafeZone)
        {
            playerTypesDict = new Dictionary<PlayerTypes, PlayerTileData>();
            foreach (var placement in placementPoints)
            {
                placementQueue.Enqueue(placement);
            }
        }
    }

    public void InitPlayerPawn(PlayerPawn playerPawn, PlayerTypes playerType)
    {
        PlayerPawn = playerPawn;
        if (isSafeZone)
        {
            if (!playerTypesDict.ContainsKey(playerType))
            {
                playerTypesDict.Add(
                    playerType, 
                    new PlayerTileData { playerCount = 1, placementTransform = placementQueue.Dequeue(), // TODO :: Change indexing logic
                    playerPawns = new List<PlayerPawn> { playerPawn }
                });
            }
            else
            {
                playerTypesDict[playerType].playerCount++;
                playerTypesDict[playerType].playerPawns.Add(playerPawn);
            }
        }
    }

    public void UpdateSafeZonePlayerData(PlayerTypes playerType)
    {
        if (!IsSafeZone) return;

        if (playerTypesDict.ContainsKey(playerType))
        {
            if (playerTypesDict[playerType].playerCount > 0)
            {
                playerTypesDict[playerType].playerCount--;
                playerTypesDict[playerType].playerPawns.RemoveAt(playerTypesDict[playerType].playerPawns.Count - 1);
                if (playerTypesDict[playerType].playerCount == 0)
                {
                    placementQueue.Enqueue(playerTypesDict[playerType].placementTransform);
                    playerTypesDict.Remove(playerType);
                    lastOccupiedIndex--;
                }
            }
        }
    }

    public PlayerTypes GetFirstPlayerType() => playerTypesDict.Keys.FirstOrDefault();

    public int GetPlayerPawnsCountInTile(PlayerTypes playerType)
    {
        return playerTypesDict[playerType].playerPawns.Count;
    }

    public PlayerPawn IterateAndGetPlayerPawn(PlayerTypes playerType, int index)
    {
        return playerTypesDict[playerType].playerPawns[index];
    }

    public Transform GetPlacementPoint(PlayerTypes playerType)
    {
        return playerTypesDict[playerType].placementTransform;
    }
}
