package bagaturchess.bitboard.bughouse;

import bagaturchess.bitboard.api.IInternalMoveList;
import bagaturchess.bitboard.impl.movelist.BaseMoveList;
import bagaturchess.bitboard.impl1.BoardImpl;

import java.util.ArrayList;

public class BughouseMoveGen {
    int movesCounter = 0;
    BughousePositionsBuilder builder;

    public BughouseMoveGen() {
        this.builder = new BughousePositionsBuilder();
    }


    public ArrayList<String> generateFENsFromClassicMovesFromPosition(String currentFENPosition) {
        IInternalMoveList[] lists = new IInternalMoveList[4];
        BoardImpl currentBoard = new BoardImpl(currentFENPosition, null);
        for (int i = 0; i < lists.length; i++) {
            lists[i] = new BaseMoveList();
        }
        movesCounter = 0;
        ArrayList<Integer> possibleMovesInts = new ArrayList<>();

        lists[0].reserved_clear();
        currentBoard.genAllMoves(lists[0]);
        for (int j = 0; j < lists[0].reserved_getCurrentSize(); j++) {
            possibleMovesInts.add(lists[0].reserved_getMovesBuffer()[j]);
            movesCounter++;
        }

        ArrayList<String> possibleMoves = new ArrayList<>();
        for (int j = 0; j < possibleMovesInts.size(); j++) {
            currentBoard.makeMoveForward(possibleMovesInts.get(j));
            possibleMoves.add(currentBoard.toString());
            currentBoard.makeMoveBackward(possibleMovesInts.get(j));
        }
        return possibleMoves;
    }


    public ArrayList<String> generateBughouseMovesFromFEN(String position, ArrayList<Character> availablePieces) {
        char turnToMove = position.split(" ")[1].charAt(0);
        ArrayList<String> bughouseDropMoves = new ArrayList<>();
        for (Character piece: availablePieces) {
            bughouseDropMoves.addAll(generatePossibleBughouseMovesWithPiece(piece, turnToMove, position));
        }
        return bughouseDropMoves;
    }


    public ArrayList<String> generatePossibleBughouseMovesWithPiece(Character piece, Character turnToMove,
                                                                    String positionFEN) {
        boolean inCheck = builder.isCurrentPositionInCheck(positionFEN);

        String[] splitGame = positionFEN.split(" ");
        String sideToMove = splitGame[1];
        String game = splitGame[0];
        char nextSideToMove = (game.charAt(0) == 'w') ? 'b' : 'w';
        // resets 3-move repetition counter
        splitGame[4] = "0";
        // resets 50-move rule counter
        splitGame[5] = String.valueOf(Integer.parseInt(splitGame[5]) + 1);
        String rest = " " + nextSideToMove + " " + splitGame[2] + " " + splitGame[3] + " " + splitGame[4] + " " + splitGame[5]
                + " " + piece;
        String isInCheckTest = " " + turnToMove + " " + splitGame[2] + " " + splitGame[3] + " " +
                splitGame[4] + " " + splitGame[5];
        ArrayList<String> positions = new ArrayList<>();

        if ((Character.isLowerCase(piece) && sideToMove.charAt(0) == 'b') ||
                (Character.isUpperCase(piece) && sideToMove.charAt(0) == 'w')) {

            if (turnToMove == sideToMove.charAt(0)) {
                for (int i = 0; i < game.length(); i++) {
                    char currentChar = game.charAt(i);

                    if (currentChar >= '1' && currentChar <= '8') {
                        String left = game.substring(0, i);
                        String right = game.substring(i + 1);
                        ArrayList<String> bughouseMoves = new ArrayList<>(builder.getBughouseDropMovesVariants
                                (Character.getNumericValue(currentChar), piece));

                        for (String move : bughouseMoves) {
                            boolean inCheckAfterMove =
                                    builder.isCurrentPositionInCheck((left + move + right + isInCheckTest));
                            if (!(inCheck && inCheckAfterMove)) {
                                positions.add(left + move + right + rest);
                            }
                        }
                    }
                }
            }
        }
        return positions;
    }

}


