//
// Created by hamac on 20.12.2024.
//

#ifndef CHESSBOARD_H
#define CHESSBOARD_H

#include "Chesspiece.h"
#include <queue>
#include <string>
#include <vector>
#include <unordered_map>

class Chessboard {
  private:
    /* Constants */
    // Chars to display board
    // Corners
    const std::string topLeft = "┌";
    const std::string topRight = "┐";
    const std::string bottomLeft = "└";
    const std::string bottomRight = "┘";

    // Line chars
    const std::string horizontal = "─";
    const std::string vertical = "│";
    const std::string topIntersection = "┬";
    const std::string bottomIntersection = "┴";
    const std::string middleIntersection = "┼";

    // White pieces
    const std::string whiteSquare = "□";
    const std::string whiteKing = "♔";
    const std::string whiteQueen = "♕";
    const std::string whiteRook = "♖";
    const std::string whiteBischop = "♗";
    const std::string whiteKnight = "♘";
    const std::string whitePawn = "♙";

    // Black pieces
    const std::string blackSquare = "■";
    const std::string blackKing = "♚";
    const std::string blackQueen = "♛";
    const std::string blackRook = "♜";
    const std::string blackBischop = "♝";
    const std::string blackKnight = "♞";
    const std::string blackPawn = "♟";

    /* class fields */
    std::vector<std::vector<char>> currentBoard;

    std::unordered_map<char, std::vector<std::unique_ptr<Chesspiece>>> playingPieces;

    // Starting formatting
    std::vector<std::vector<char>> startBoard = {
        {'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'},
        {'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'},
        {'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
        {'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
        {'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
        {'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
        {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'},
        {'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R'},
    };

    // ToDo: Mathematisch sicherlich weg rationalisierbar
    std::vector<std::vector<char>> emptyBoard = {
        {'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
        {'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
        {'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
        {'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
        {'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
        {'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
        {'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
        {'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'}
    };

    // Saves turn order; true = white and false = black
    bool turnOrder = true;

    // ToDo: Max Size definieren?
    std::queue<std::string> queue;

    /* methods */
    // Method returns unicode for chess icon depending on the identifier
    std::string getChessIcon(char identifier);

    void generateTopLine();

    void generatePlayingField(const std::vector<std::vector<char>>& chessboard);

    void generateBottomLine();

  public:
    /* fields */
    std::string display;
    int boardSize = 8;

    /* methods */
    bool getTurnOrder();
    void setTurnOrder(bool turnOrder);

    std::vector<std::vector<char>> getBoard();
    void setBoard(std::vector<std::vector<char>> board);

    std::vector<std::vector<char>> getStartBoard();

    std::vector<std::vector<char>> getEmptyBoard();

    void draw ();

    void draw (const std::vector<std::vector<char>>& chessboard);

    void init();

    void initPieces();

    void move();

    char getCorrectPiece(char pieceIdentifier);

    //
    void move(std::string move);

    // This method saves the current board state
    void saveBoard();

    // This method loads a save state
    void loadBoard(std::string filepath);
};


#endif //CHESSBOARD_H