Source: web/src/components/Window/WindowContent/ServerPanel.js

import React, { useState, useEffect, useCallback } from "react";
import "./serverPanel.css";
import Button from "../../button/Button.tsx";
import ListTableItem from "./SpecificComponentWindow/ListTableItem";
import { useWindowContext } from "../../Utiles/WindowContext.jsx";
import { useTranslation } from "../../Utiles/Translations";
import { useDispatch, useSelector } from "react-redux";
import { useAuth } from "../../Utiles/AuthProvider.jsx";
import * as actions from "../../../store/actions/clientInteractionsCreator.js";
import TextInputComponent from "../../textInput/TextInput.jsx";

/**
 * ServerPanelWindow component manages the display of available game rooms,
 * including pagination, search functionality, and the ability to join rooms.
 */
const ServerPanelWindow = () => {
  const dispatch = useDispatch();
  const { getTranslatedWord } = useTranslation();

  const { closeWindow, showGameTable, setWindowType, openWindow } =
    useWindowContext();

  const { getRoomTableRecords, isLogged } = useAuth();
  const [roomTableRecords, setRoomTableRecords] = useState([]);

  const [currentPage, setCurrentPage] = useState(1);
  const [recordsPerPage, setRecordsPerPage] = useState(6);

  const [searchText, setSearchText] = useState("");

  const isPlayerSited = useSelector((state) => state.game.playerSited);

  // Displays the game room UI when the player is sited. => used in loadingWindow
  const displayGameRoom = useCallback(() => {
    showGameTable();
    closeWindow();
    setWindowType("");
  }, [showGameTable, closeWindow, setWindowType]);

  // UseEffect to handle the player sited state and display the game room accordingly.
  useEffect(() => {
    if (isPlayerSited) {
      displayGameRoom();
    }
  }, [isPlayerSited, displayGameRoom]);

  // Manage the number of tables displayed per page based on window height.
  useEffect(() => {
    const updateRecordsPerPage = () => {
      const windowHeight = window.innerHeight;
      const tableItemHeight = 130;
      const maxRecordsPerPage = Math.floor(
        (windowHeight * 0.9) / tableItemHeight
      );
      setRecordsPerPage(maxRecordsPerPage);
    };

    updateRecordsPerPage();

    const handleResize = () => {
      updateRecordsPerPage();
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  const handleChange = (event) => {
    setSearchText(event.target.value); // Mettre à jour le texte de recherche lorsqu'il y a un changement dans la barre de recherche
  };

  // Fetch room table records from the server and update the state.
  const fetchRoomTableRecords = useCallback(async () => {
    try {
      const authToken = sessionStorage.getItem("authToken");
      if (authToken) {
        const data = await getRoomTableRecords(authToken);
        if (data) {
          // Diviser les tables en deux groupes : tables pleines et tables non pleines
          const fullTables = data.filter(
            (table) => table.players.length === 10
          );
          const nonFullTables = data.filter(
            (table) => table.players.length < 10
          );

          // Trier les tables non pleines dans l'ordre décroissant du nombre de joueurs
          const sortedNonFullTables = nonFullTables.sort(
            (a, b) => b.players.length - a.players.length
          );

          // Fusionner les deux groupes de tables en plaçant les tables pleines à la fin
          const sortedTables = [...sortedNonFullTables, ...fullTables];

          // Filtrer les tables en fonction du texte de recherche
          const filteredTables = sortedTables.filter((table) =>
            table.serverName.toLowerCase().includes(searchText.toLowerCase())
          );

          // Mettre à jour l'état roomTableRecords avec les tables triées et filtrées
          setRoomTableRecords(filteredTables);
        }
      }
    } catch (error) {
      console.error("Error fetching roomTableRecords:", error);
    }
  },[searchText,getRoomTableRecords]);

  useEffect(() => {
    fetchRoomTableRecords();
  }, [searchText, fetchRoomTableRecords]);

  useEffect(() => {
    setCurrentPage(1);
  }, [searchText]);

  // Handle the logic for joining a table.
  const handleJoinTable = (id) => {
    if (isLogged) {
      openWindow("loading");
      dispatch(actions.joinRoom(id));
      if (isPlayerSited) {
        displayGameRoom();
      } else {
      }
    }
  };

  const indexOfLastRecord = currentPage * recordsPerPage;
  const indexOfFirstRecord = indexOfLastRecord - recordsPerPage;
  const currentRecords = roomTableRecords.slice(
    indexOfFirstRecord,
    indexOfLastRecord
  );

  const paginate = (pageNumber) => setCurrentPage(pageNumber);
  const totalPages = Math.ceil(roomTableRecords.length / recordsPerPage);

  return (
    <div className="listTableWindowPanel">
      <TextInputComponent
        placeholder="serverPanel.search"
        styleClass={"input-connectionDefault input-searchBar"}
        iconSrc="static/media/assets/images/icons/black/search.png"
        styleClass2={"container-textInputComponent2"}
        errorMessage={""}
        onChange={handleChange}
      />
      <Button 
        styleClass={"btn-serverRefresh"}
        onClick={fetchRoomTableRecords}
        iconSrc="static/media/assets/images/icons/white/refresh.png"
        />

      <div className="listTableHeader">
        <div className="headerItem">
          {getTranslatedWord("serverPanel.name")}
        </div>
        <div className="headerItem">
          {getTranslatedWord("serverPanel.rank")}
        </div>
        <div className="headerItem">{getTranslatedWord("game.players")}</div>
        <div className="headerItem"></div>
        <div className="headerItem"></div>
      </div>
      <div className="listTableBody">
        {currentRecords.map((table, index) => (
          <ListTableItem
            key={index}
            id={table._id}
            nom={table.serverName}
            rang={table.rank}
            onJoinClick={() => handleJoinTable(table._id)}
            nombreDeJoueurs={table.players.length}
            ouvert={table.roomPassword ? false : true}
          />
        ))}
      </div>
      <div className="container-pagination">
        {/* Bouton pour la première page */}
        <Button
          styleClass={
            currentPage === 1
              ? "back-color1 btn-serverPage"
              : "back-color3 btn-serverPage"
          }
          label={"1"}
          onClick={() => paginate(1)}
        />

        {/* Bouton pour la page précédente (n-1) */}
        {currentPage > 2 && (
          <Button
            styleClass={"back-color3 btn-serverPage"}
            label={currentPage - 1}
            onClick={() => paginate(currentPage - 1)}
          />
        )}

        {/* Bouton pour la page actuelle (n) */}
        {currentPage !== 1 && currentPage !== totalPages && (
          <Button
            styleClass={"back-color1 btn-serverPage"}
            label={currentPage}
            onClick={() => paginate(currentPage)}
          />
        )}

        {/* Bouton pour la page suivante (n+1) */}
        {currentPage < totalPages - 1 && (
          <Button
            styleClass={"back-color3 btn-serverPage"}
            label={currentPage + 1}
            onClick={() => paginate(currentPage + 1)}
          />
        )}

        {/* Bouton pour la dernière page */}
        {totalPages > 1 && (
          <Button
            styleClass={
              currentPage === totalPages
                ? "back-color1 btn-serverPage"
                : "back-color3 btn-serverPage"
            }
            label={totalPages}
            onClick={() => paginate(totalPages)}
          />
        )}
      </div>
    </div>
  );
};

export default ServerPanelWindow;