namespace API.Models.Game
{
    public class Coordinates
    {
        public int X;
        public int Y;
    }

    public enum PlaceResult
    {
        OutOfGameField,
        NotAllowedPlayer,
        OccupiedRed,
        OccupiedYellow,
        InvalidFieldValue,
        Placed
    }

    public enum FieldState
    {
        OutOfGameField,
        Empty,
        OccupiedRed,
        OccupiedYellow,
        InvalidFieldValue
    }

    public class GameField(Coordinates gFs)
    {
        public int[,] CurrentField { get; } = new int[gFs.Y, gFs.X];
        public int[,] BackupField { get; } = new int[gFs.Y, gFs.X];

        public PlaceResult Place(Coordinates coordinates, int player)
        {
            if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) ||
                coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0))
            {
                return PlaceResult.OutOfGameField;
            }

            if (player != 1 && player != 2)
                return PlaceResult.NotAllowedPlayer;

            int currentValue = CurrentField[coordinates.Y, coordinates.X];

            if (currentValue != 0)
            {
                return currentValue switch
                {
                    1 => PlaceResult.OccupiedRed,
                    2 => PlaceResult.OccupiedYellow,
                    _ => PlaceResult.InvalidFieldValue
                };
            }

            CreateSave();
            CurrentField[coordinates.Y, coordinates.X] = player;

            return PlaceResult.Placed;
        }

        public FieldState CheckField(Coordinates coordinates)
        {
            if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) ||
                coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0))
            {
                return FieldState.OutOfGameField;
            }

            int currentValue = CurrentField[coordinates.Y, coordinates.X];

            return currentValue switch
            {
                0 => FieldState.Empty,
                1 => FieldState.OccupiedRed,
                2 => FieldState.OccupiedYellow,
                _ => FieldState.InvalidFieldValue
            };
        }

        private void CreateSave()
        {
            Array.Copy(CurrentField, BackupField, CurrentField.Length);
        }
    }
}