#include "../Chessboard/ChessboardVisualizerGraphic.hpp"
#include "../ChessPieces/ChessPiecePosition.hpp"
#include "../Visualizer/HistorieVisualizer.hpp"
#include "../Visualizer/BaseVisualizer.hpp"

/*void ChessboardVisualizerGraphic::SetConsoleColor(Colors foreground, Colors background) {
  const std::string SEQ_FOREGROUND = "\x1b[3";
  const std::string SEQ_FOREGROUND_LIGHT = "\x1b[9";
  const std::string SEQ_BACKGROUND = "\x1b[4";
  const std::string SEQ_BACKGROUND_LIGHT = "\x1b[10";

  // set foreground color
  switch (foreground) {
    case BLACK:
    case RED:
    case GREEN:
    case YELLOW:
    case BLUE:
    case MAGENTA:
    case CYAN:
    case WHITE:
      std::cout << SEQ_FOREGROUND << foreground << "m";
      break;
    case LIGHT_BLACK:
    case LIGHT_RED:
    case LIGHT_GREEN:
    case LIGHT_YELLOW:
    case LIGHT_BLUE:
    case LIGHT_MAGENTA:
    case LIGHT_CYAN:
    case LIGHT_WHITE:
      std::cout << SEQ_FOREGROUND_LIGHT << foreground << "m";
      break;
    case DEFAULT:
    default:
      std::cout << SEQ_FOREGROUND << foreground << "m";
      break;
  }

  // set background color
  switch (background) {
    case BLACK:
    case RED:
    case GREEN:
    case YELLOW:
    case BLUE:
    case MAGENTA:
    case CYAN:
    case WHITE:
      std::cout << SEQ_BACKGROUND << background << "m";
      break;
    case LIGHT_BLACK:
    case LIGHT_RED:
    case LIGHT_GREEN:
    case LIGHT_YELLOW:
    case LIGHT_BLUE:
    case LIGHT_MAGENTA:
    case LIGHT_CYAN:
    case LIGHT_WHITE:
      std::cout << SEQ_BACKGROUND_LIGHT << background << "m";
      break;
    case DEFAULT:
    default:
      std::cout << SEQ_BACKGROUND << background << "m";
      break;
  }
}

void ChessboardVisualizerGraphic::temp(Chessboard* chessboard) {
  for (int rank = 8; rank >= 1; rank--) {
    if (rank == 8) GenerateTopOrBottomBorder(true);

    std::vector<std::string> temp;

    for (int heightOfField = 0; heightOfField < 3; heightOfField++) {
      for (char file = 'A'; file <= 'H'; file++) {
        if (file == 'A') {
          temp.push_back((heightOfField == 1) ? " " + std::to_string(rank) + " " : "   ");
          temp.push_back(ChessboardVisualizerGraphic::VERTICAL_LINE);
        }

        temp.push_back(GenerateBoardField(chessboard, file, rank, heightOfField));

        if (file == 'H') {
          this->SetConsoleColor(DEFAULT, DEFAULT);
          temp.push_back(ChessboardVisualizerGraphic::VERTICAL_LINE);
        }
      }
      AddRowToBoard(temp);
      temp.clear();
      this->SetConsoleColor(DEFAULT, DEFAULT);
    }
    if (rank == 1) GenerateTopOrBottomBorder(false);
  }
}

void ChessboardVisualizerGraphic::AddMenusToChessboard() {

}

void ChessboardVisualizerGraphic::GenerateChessboard(Chessboard* chessboard) {
  ClearTerminal();

  board.clear();

  GeneratePlayers(chessboard);

  temp(chessboard);

  AddMenusToChessboard();

  /*HistorieVisualizer history = HistorieVisualizer(15, 3, "Me", "Me");

  std::vector<std::vector<std::string>> historyDisplayVector = history.GetDisplayVector();
  std::vector<std::vector<std::string>> currentBoard = board;

  for (size_t i = 0; i < historyDisplayVector.size(); i++) {
    for (size_t j = 0; j < historyDisplayVector[i].size(); j++) {
      board[i].push_back("         " + historyDisplayVector[i][j]);
    }
  }*/



  /*this->SetConsoleColor(DEFAULT, DEFAULT);
  DrawFromVector();
}

void ChessboardVisualizerGraphic::Draw(Chessboard* chessboard) {
  ClearTerminal();

  DrawPlayers(chessboard);

  for (int rank = 8; rank >= 1; rank--) {
    if (rank == 8) DrawTopOrBottomBorder(true);

    for (int heightOfField = 0; heightOfField < 3; heightOfField++) {
      for (char file = 'A'; file <= 'H'; file++) {
        if (file == 'A') {
          (heightOfField == 1) ? std::cout << " " << rank << " " : std::cout << "   ";
          std::cout << ChessboardVisualizerGraphic::VERTICAL_LINE;
        }

        DrawBoardField(chessboard, file, rank, heightOfField);

        if (file == 'H') {
          this->SetConsoleColor(DEFAULT, DEFAULT);
          std::cout << ChessboardVisualizerGraphic::VERTICAL_LINE;
        }
      }
      this->SetConsoleColor(DEFAULT, DEFAULT);
      std::cout << std::endl;
    }
    if (rank == 1) DrawTopOrBottomBorder(false);
  }
  this->SetConsoleColor(DEFAULT, DEFAULT);
  std::cout << std::endl;
}

void ChessboardVisualizerGraphic::GenerateTopOrBottomBorder(bool top) {
  std::vector<std::string> temp;

  temp.push_back("   ");

  std::string left = (top) ? ChessboardVisualizerGraphic::TOP_LEFT_CORNER : ChessboardVisualizerGraphic::BOTTOM_LEFT_CORNER;
  temp.push_back(left);

  for (int i = 0; i < 8; i++) {
    temp.push_back(ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE);
  }

  std::string right = (top) ? ChessboardVisualizerGraphic::TOP_RIGHT_CORNER : ChessboardVisualizerGraphic::BOTTOM_RIGHT_CORNER;
  temp.push_back(right);

  AddRowToBoard(temp);
  if (!top) GenerateFiles();
}

void ChessboardVisualizerGraphic::DrawTopOrBottomBorder(bool top) {
  std::cout << "   ";

  std::string left = (top) ? ChessboardVisualizerGraphic::TOP_LEFT_CORNER : ChessboardVisualizerGraphic::BOTTOM_LEFT_CORNER;
  std::cout << left;

  for (int i = 0; i < 8; i++) {
    std::cout << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE;
  }

  std::string right = (top) ? ChessboardVisualizerGraphic::TOP_RIGHT_CORNER : ChessboardVisualizerGraphic::BOTTOM_RIGHT_CORNER;
  std::cout << right;

  std::cout << std::endl;
  if (!top) DrawFiles();
}

void ChessboardVisualizerGraphic::GenerateFiles() {
  std::vector<std::string> temp;

  for (char file = 'A'; file <= 'H'; file++) {
    if (file == 'A') {
      temp.push_back("    ");
    }

    temp.push_back("   " + std::string(1, file) + "   ");

    if (file == 'H') {
      temp.push_back(" ");
     }
  }
  AddRowToBoard(temp);
}

void ChessboardVisualizerGraphic::DrawFiles() {
  for (char file = 'A'; file <= 'H'; file++) {
    if (file == 'A') {
      std::cout << "    ";
    }

    std::cout << "   " << file << "   ";

    if (file == 'H') {
       std::cout << " ";
    }
  }
  std::cout << std::endl;
}

std::string ChessboardVisualizerGraphic::GenerateBoardField(Chessboard* chessboard, char file, int rank, int height) {
  if (height == 1) {
    ChessPiecePosition* position = new ChessPiecePosition(file, rank);

    if (chessboard->IsEmptyField(position)) {
      return "       ";
    } else {
      ChessPiece* piece = chessboard->GetChessPiece(position);
      return "   " + piece->GetUnicode() + "   ";
    }
  } else {
    return "       ";
  }
}

void ChessboardVisualizerGraphic::DrawBoardField(Chessboard* chessboard, char file, int rank, int height) {
  if (file % 2 == (rank % 2)) {
    this->SetConsoleColor(BLACK, WHITE);
  } else {
    this->SetConsoleColor(WHITE, BLACK);
  }

  if (height == 1) {
    ChessPiecePosition* position = new ChessPiecePosition(file, rank);

    if (chessboard->IsEmptyField(position)) {
      std::cout << "       ";
    } else {
      ChessPiece* piece = chessboard->GetChessPiece(position);
      std::cout << "   " << piece->GetUnicode() << "   ";
    }
  } else {
    std::cout << "       ";
  }
}

void ChessboardVisualizerGraphic::ClearTerminal() {
  //std::cout << "\033[2J"; // clear the console
  system("cls");
}

void ChessboardVisualizerGraphic::GeneratePlayers(Chessboard* chessboard) {
  std::vector<std::string> temp;
  temp.push_back("   ");
  temp.push_back(chessboard->GetPlayer(ChessPieceColor::White)->GetName() + " vs. " + chessboard->GetPlayer(ChessPieceColor::Black)->GetName());
  AddRowToBoard(temp);
}

void ChessboardVisualizerGraphic::DrawPlayers(Chessboard* chessboard) {
  std::cout << "   ";
  std::cout << chessboard->GetPlayer(ChessPieceColor::White)->GetName() + " vs. " + chessboard->GetPlayer(ChessPieceColor::Black)->GetName();
  std::cout << std::endl;
}

void ChessboardVisualizerGraphic::AddRowToBoard(const std::vector<std::string>& row) {
  board.push_back(row);
}

// board[2] bis board[25] Feld des Schachbretts
// in vectoren von 2 bis 25 index von 2 bis 9
void ChessboardVisualizerGraphic::DrawFromVector() {
  size_t lengthOfBoard = BaseVisualizer::GetSumAllCharsFromVector(board[1]);
  for (int row = 0; row < board.size(); ++row) {
    for (int column = 0; column < board[row].size(); ++column) {
      if (row >= 2 && row <= 25 && column >= 2 && column <= 9) {
        bool isSecondRowOfField = (row % 3 == 2);
        bool isBlackWhite = (column % 2 == row % 2);

        if ((row - 1) % 3 == 0) { // Change after 3 rows
          if (isSecondRowOfField) {
            this->SetConsoleColor(isBlackWhite ? WHITE : BLACK, isBlackWhite ? BLACK : WHITE);
          } else {
            this->SetConsoleColor(isBlackWhite ? BLACK : WHITE, isBlackWhite ? WHITE : BLACK);
          }
        } else {
          if (isSecondRowOfField) {
            this->SetConsoleColor(isBlackWhite ? BLACK : WHITE, isBlackWhite ? WHITE : BLACK);
          } else {
            this->SetConsoleColor(isBlackWhite ? WHITE : BLACK, isBlackWhite ? BLACK : WHITE);
          }
        }
      }
      //std::cout << std::setw(lengthOfBoard) << board[row][column];

      this->SetConsoleColor(DEFAULT, DEFAULT);
    }
    this->SetConsoleColor(DEFAULT, DEFAULT);
    std::cout << std::endl;
  }
}*/