using Kalaha.Api.Database;
using Kalaha.Api.Database.Models;
using Microsoft.AspNetCore.Mvc;


namespace Kalaha.Api.Controllers.Helper
{
    public static class GameControllerHelper
    {
        public const int Player1KalahaIdx = 6;
        public const int Player2KalahaIdx = 13;

        /// <summary>
        /// Führt den Spielzug aus
        /// </summary>
        /// <param name="game"></param>
        /// <param name="playerId"></param>
        /// <param name="startPos">Gewählte Mulde</param>
        /// <returns>Gibt zurück, ob der Spieler noch einen Extra-Zug hat</returns>
        public static bool PlayMove(Game game, Guid playerId, int startPos)
        {
            bool isPlayer1 = game.Player1Id == playerId;
            int opponentKalaha = isPlayer1 ? Player2KalahaIdx : Player1KalahaIdx;
            int myKalaha = isPlayer1 ? Player1KalahaIdx : Player2KalahaIdx;

            int stones = game.BoardState[startPos];
            game.BoardState[startPos] = 0; // Mulde leeren

            int currentPos = startPos;

            // Steine aus gewähltem Bucket verteilen
            while (stones > 0)
            {
                currentPos = (currentPos + 1) % 14;

                if (currentPos == opponentKalaha) continue;

                game.BoardState[currentPos]++;
                stones--;
            }

            // Wenn der letzte Stein in einer eigenen, zuvor leeren Mulde landet und der
            // Gegner Steine in der gegenüberliegenden Mulde hat, werden alle Steine in 
            // die Kalaha des Spielers gelegt
            if (currentPos != myKalaha && game.BoardState[currentPos] == 1 && IsOwnPit(currentPos, isPlayer1))
            {
                int oppositePos = 12 - currentPos;

                if (game.BoardState[oppositePos] > 0)
                {
                    game.BoardState[myKalaha] += game.BoardState[oppositePos] + 1;
                    game.BoardState[currentPos] = 0;
                    game.BoardState[oppositePos] = 0;
                }
            }

            CheckGameOver(game);

            // Landet der letzte Stein im eigenen Kalaha, ist man nochmal dran
            return currentPos == myKalaha;
        }

        private static bool IsOwnPit(int pos, bool isPlayer1)
        {
            // Spieler 1 gehören Mulden 0-5, Spieler 2 gehören 7-12
            return isPlayer1 ? (pos >= 0 && pos <= 5) : (pos >= 7 && pos <= 12);
        }

        /// <summary>
        /// Prüfen ob das Spiel vorbei ist, falls eine der beiden Seiten komplett leer ist.
        /// Falls eine Seite leer ist, werden die übrigen Steine in die Kalaha des Spielers gelegt.
        /// </summary>
        /// <param name="game"></param>
        private static void CheckGameOver(Game game)
        {
            bool player1Empty = true;
            for (int i = 0; i <= 5; i++) if (game.BoardState[i] > 0) player1Empty = false;

            bool player2Empty = true;
            for (int i = 7; i <= 12; i++) if (game.BoardState[i] > 0) player2Empty = false;

            if (player1Empty || player2Empty)
            {
                // Restliche Steine ins jeweilige Kalaha räumen
                for (int i = 0; i <= 5; i++)
                {
                    game.BoardState[Player1KalahaIdx] += game.BoardState[i];
                    game.BoardState[i] = 0;
                }
                for (int i = 7; i <= 12; i++)
                {
                    game.BoardState[Player2KalahaIdx] += game.BoardState[i];
                    game.BoardState[i] = 0;
                }

                game.State = GameState.Finished;
            }
        }

        public static void RandomizeStartingPlayer(Game game)
        {
            Random random = new Random();
            if(random.Next(1) > 0)
            {
                game.ActivePlayerId = game.Player2Id;
            }
            else
            {
                game.ActivePlayerId = game.Player1Id;
            }
        }
    }
}

