package org.example.mesosll07;

import Server.Automaton.Game;
import Server.Era;
import Server.Player;
import Server.TotemColor;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import Server.Cards.*;

import java.nio.file.Paths;
public class DeckGridAppFX extends Application {

    private static final Logger logger = LogManager.getLogger(DeckGridAppFX.class);

    private PDDocument documentFront;
    private PDDocument documentBack;
    private PDFRenderer pdfRendererFront;
    private PDFRenderer pdfRendererBack;
    private int totalCards = 0;

    // Contenitori Layout
    private HBox topRow;
    private HBox centerRow;
    private HBox bottomRow;
    private HBox playersArea; // NUOVO: Area per i giocatori
    private Button btnShuffle;



    // --------------------------------

    @Override
    public void start(Stage primaryStage) {

        List<Player> players = new ArrayList<>();
        players.add(new Player("Yoshi", TotemColor.YELLOW));
        players.add(new Player("Pippo", TotemColor.PURPLE));
        players.add(new Player("John", TotemColor.RED));
        players.add(new Player("Baggio", TotemColor.BLUE));
        players.add(new Player("Gino", TotemColor.GREEN));

        Game game = new Game(players);

        InputStream frontStream = getClass().getResourceAsStream("/files/Cards_total_front_PROMO.pdf");
        InputStream backStream = getClass().getResourceAsStream("/files/Cards_total_back_PROMO.pdf");
        InputStream csvStream = getClass().getResourceAsStream("/files/cards.csv");

        try {
            documentFront = PDDocument.load(frontStream);
            pdfRendererFront = new PDFRenderer(documentFront);

            documentBack = PDDocument.load(backStream);
            pdfRendererBack = new PDFRenderer(documentBack);

        } catch ( IOException e) {
            throw new RuntimeException(e);
        }
        //File fileCsv = new File(getClass().getResource("/files/cards.csv").toURI());
        game.newGame(csvStream);




        primaryStage.setTitle("Tavolo da Gioco - Board & Players");


        btnShuffle = new Button("Rimescola & Distribuisci");
        btnShuffle.setDisable(true);


        btnShuffle.setOnAction(e -> distributeAll(game));

        HBox topMenu = new HBox(15, btnShuffle);
        topMenu.setAlignment(Pos.CENTER);
        topMenu.setPadding(new Insets(10));

        topRow = createRowContainer();
        centerRow = createRowContainer();
        bottomRow = createRowContainer();



        // NUOVO: Inizializza l'area giocatori
        playersArea = new HBox(30);
        playersArea.setAlignment(Pos.CENTER);
        playersArea.setPadding(new Insets(20));

        distributeAll(game);
        VBox tableArea = new VBox(20,
                new Label("TOP"), topRow,
                new Label("CENTER "), centerRow,
                new Label("DOWN"), bottomRow,
                new Label("--- SITUAZIONE GIOCATORI ---"), playersArea
        );
        tableArea.setAlignment(Pos.CENTER);
        tableArea.setPadding(new Insets(20));

        ScrollPane scrollPane = new ScrollPane(tableArea);
        scrollPane.setFitToWidth(true);

        BorderPane root = new BorderPane();
        root.setTop(topMenu);
        root.setCenter(scrollPane);

        Scene scene = new Scene(root, 1300, 900);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private HBox createRowContainer() {
        HBox row = new HBox(10);
        row.setAlignment(Pos.CENTER);
        return row;
    }



    private void distributeAll(Game game) {
        if (documentFront == null) return;

        topRow.getChildren().clear();
        centerRow.getChildren().clear();
        bottomRow.getChildren().clear();
        playersArea.getChildren().clear();

        List<Integer> deck = new ArrayList<>();
        for (int i = 0; i < 118; i++) deck.add(i);
        Collections.shuffle(deck);

        // Distribuisce sul tavolo le prime 21 carte
        int index = 0;
        index = populateTable(topRow, deck, index, 8);
        index = populateTable(centerRow, deck, index, 6);
        index = populateTable(bottomRow, deck, index, 7);

        // NUOVO: Simula 2 giocatori con le carte rimanenti
        Random rand = new Random();
        List<Player> players =game.getPlayers();

        // Assegna 5 carte a caso a ogni giocatore e simula il loro Tipo



        for (Player p : players) {
            for (int j=0;j<4;j++){
                int idx = rand.nextInt(game.getGameBoard().getCardDeck().getTribeDeck().size());
                Card c = game.getGameBoard().getCardDeck().drawTribeOne();
                p.getPlayerTribe().addCharacter((CharacterCard) c);
            }
            for (int j=0;j<2;j++){
                int idx = rand.nextInt(game.getGameBoard().getCardDeck().getBuildingDeck(Era.I).size());
                Card c = game.getGameBoard().getCardDeck().drawBuildingOne(Era.I);
                p.getPlayerTribe().addBuilding((BuildingCard) c);
            }

        }

        // Renderizza i giocatori nella UI
        renderPlayers(players);
    }

    private int populateTable(HBox row, List<Integer> deck, int startIndex, int amount) {
        for (int i = 0; i < amount; i++) {
            if (startIndex >= deck.size()) break;
            ImageView card = createCardImage(deck.get(startIndex), 150, true); // Altezza 150px
            if (card != null) row.getChildren().add(card);
            startIndex++;
        }
        return startIndex;
    }

    // --- NUOVO: RENDERIZZAZIONE GIOCATORI E RAGGRUPPAMENTO (JAVA 8) ---
    private void renderPlayers(List<Player> players) {
        for (Player player : players) {
            VBox playerBox = new VBox(10);
            playerBox.setPadding(new Insets(15));
            playerBox.setStyle("-fx-border-color: #555; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-color: #f9f9f9; -fx-background-radius: 10;");

            // Intestazione Giocatore
            Label nameLbl = new Label(player.getNickname());
            nameLbl.setFont(Font.font("System", FontWeight.BOLD, 16));

            // Risorse Cibo e Soldi
            Label statsLbl = new Label("🍖 Cibo: " + player.getFoodTokens() + "   |   💰 Money: " + player.getPrestigePoints());
            statsLbl.setTextFill(Color.DARKRED);
            statsLbl.setFont(Font.font("System", FontWeight.BOLD, 14));

            playerBox.getChildren().addAll(nameLbl, statsLbl);

            // JAVA 8 MAGIA: Raggruppa le carte del giocatore per Tipo!
            Map<CharacterType, List<CharacterCard>> groupedCards = player.getPlayerTribe().getCharacters().stream()
                    .collect(Collectors.groupingBy(CharacterCard::getCharacterType));

            // Itera sui gruppi creati e genera la grafica
            groupedCards.forEach((type, cardsOfType) -> {
                Label typeLbl = new Label("Tipo: " + type.name() + " (" + cardsOfType.size() + ")");
                typeLbl.setFont(Font.font("System", FontWeight.NORMAL, 12));

                HBox cardImagesRow = new HBox(5);
                for (Card c : cardsOfType) {
                    // Carte più piccole (90px) per l'area giocatore
                    ImageView img = createCardImage(c.getCardId(), 90, true);
                    if (img != null) cardImagesRow.getChildren().add(img);
                }

                playerBox.getChildren().addAll(typeLbl, cardImagesRow);
            });

            playersArea.getChildren().add(playerBox);
        }
    }

    private ImageView createCardImage(int pageIndex, int height, boolean front) {
        try {
            BufferedImage bim =null;
            if (front) bim = pdfRendererFront.renderImageWithDPI(pageIndex, 100);
            else bim = pdfRendererBack.renderImageWithDPI(pageIndex, 100);

            Image fxImage = SwingFXUtils.toFXImage(bim, null);
            ImageView imageView = new ImageView(fxImage);
            imageView.setFitHeight(height);
            imageView.setPreserveRatio(true);
            imageView.setStyle("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.4), 4, 0, 0, 0);");
            return imageView;
        } catch (IOException e) {
            logger.error("Errore rendering pagina {}", pageIndex, e);
            return null;
        }
    }

    @Override
    public void stop() throws Exception {
        if (documentFront != null) documentFront.close();
        super.stop();
    }

    public static void main(String[] args) {
        launch(args);
    }
}