package com.charpentierbalocchi.dorfjavatik.view;

import com.charpentierbalocchi.dorfjavatik.controller.ControleurJeu;
import com.charpentierbalocchi.dorfjavatik.model.Tuile;
import com.charpentierbalocchi.dorfjavatik.util.MusicPlayer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

public class FenetreJeu extends JFrame {
    private int taillePlateau; // Taille du plateau
    private TileButton[][] boutons; // Boutons représentant les cases du plateau
    private JLabel labelScore; // Label pour afficher le score
    private JLabel labelBiome1; // Label pour afficher le biome 1
    private JLabel labelBiome2; // Label pour afficher le biome 2
    private JLabel labelBiome3; // Label pour afficher le biome 3
    private JLabel labelBiome4; // Label pour afficher le biome 4
    private JLabel labelBiome5; // Label pour afficher le biome 5
    private Tuile tuileCourante; // La tuile actuellement proposée
    private ControleurJeu controleurJeu; // Instance du contrôleur de jeu
    private JPanel panelPlateau; // Panneau pour le plateau de jeu
    private JPanel panelTuileCourante; // Panneau pour la tuile courante
    private MusicPlayer musicPlayer; // Instance du lecteur de musique

    public FenetreJeu(int taillePlateau) {
        super("DorfJavaTik, par Juliette et Loris"); // Titre de la fenêtre
        this.taillePlateau = taillePlateau;
        initUI();
        this.controleurJeu = new ControleurJeu(this, taillePlateau); // Initialiser le contrôleur après la configuration
                                                                     // de l'interface
        controleurJeu.demarrerJeu(); // Démarrer le jeu après l'initialisation
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Ferme l'application à la fermeture de la fenêtre
        setSize(1300, 1000); // Fixe la taille de la fenêtre à 1300 x 1000
        setLocationRelativeTo(null); // Centre la fenêtre sur l'écran
        setVisible(true); // Rendre la fenêtre visible
        // Démarrer la musique de fond
        musicPlayer = new MusicPlayer("/com/charpentierbalocchi/dorfjavatik/resources/background.wav");
        musicPlayer.play();
    }

    private void initUI() {
        // Panel principal avec BorderLayout
        JPanel panelPrincipal = new JPanel(new BorderLayout());

        // Panel pour le plateau de jeu sur la droite
        panelPlateau = new JPanel(new GridLayout(taillePlateau, taillePlateau));
        boutons = new TileButton[taillePlateau][taillePlateau];
        for (int i = 0; i < taillePlateau; i++) {
            for (int j = 0; j < taillePlateau; j++) {
                TileButton bouton = new TileButton();
                final int x = i;
                final int y = j;
                bouton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        controleurJeu.handleTilePlacement(x, y);
                    }
                });
                boutons[i][j] = bouton;
                panelPlateau.add(bouton);
            }
        }

        // Panel pour afficher la tuile courante et le score sur la gauche, centré
        // verticalement
        JPanel panelGauche = new JPanel();
        panelGauche.setLayout(new BoxLayout(panelGauche, BoxLayout.Y_AXIS));
        panelGauche.setBorder(BorderFactory.createEmptyBorder(20, 60, 20, 60));

        labelScore = new JLabel("Score: 0");
        labelScore.setAlignmentX(Component.CENTER_ALIGNMENT);
        labelScore.setFont(new Font("Serif", Font.BOLD, 24));

        labelBiome1 = new JLabel("Rivières & Lacs : BLEU");
        labelBiome1.setAlignmentX(Component.CENTER_ALIGNMENT);
        labelBiome1.setFont(new Font("Serif", Font.PLAIN, 18));

        labelBiome2 = new JLabel("Forêts : VERT");
        labelBiome2.setAlignmentX(Component.CENTER_ALIGNMENT);
        labelBiome2.setFont(new Font("Serif", Font.PLAIN, 18));

        labelBiome3 = new JLabel("Champs : JAUNE");
        labelBiome3.setAlignmentX(Component.CENTER_ALIGNMENT);
        labelBiome3.setFont(new Font("Serif", Font.PLAIN, 18));

        labelBiome4 = new JLabel("Villages : ROUGE");
        labelBiome4.setAlignmentX(Component.CENTER_ALIGNMENT);
        labelBiome4.setFont(new Font("Serif", Font.PLAIN, 18));

        labelBiome5 = new JLabel("Montagnes : GRIS");
        labelBiome5.setAlignmentX(Component.CENTER_ALIGNMENT);
        labelBiome5.setFont(new Font("Serif", Font.PLAIN, 18));

        panelTuileCourante = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (tuileCourante != null) {
                    int size = Math.min(getWidth(), getHeight());
                    dessinerTuile(g, tuileCourante, size, size);
                }
            }
        };
        panelTuileCourante.setPreferredSize(new Dimension(150, 150));
        panelTuileCourante.setMaximumSize(new Dimension(150, 150));
        panelTuileCourante.setAlignmentX(Component.CENTER_ALIGNMENT);

        JButton boutonRecommencer = new JButton("Reset");
        boutonRecommencer.setAlignmentX(Component.CENTER_ALIGNMENT);
        boutonRecommencer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                controleurJeu.demarrerJeu();
            }
        });
        JButton boutonQuitter = new JButton("Quitter");
        boutonQuitter.setAlignmentX(Component.CENTER_ALIGNMENT);
        boutonQuitter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        panelGauche.add(Box.createVerticalGlue());
        panelGauche.add(labelScore);
        panelGauche.add(Box.createVerticalStrut(20)); // Espace entre les composants
        panelGauche.add(panelTuileCourante);
        panelGauche.add(Box.createVerticalStrut(20));
        panelGauche.add(boutonRecommencer);
        panelGauche.add(boutonQuitter);
        panelGauche.add(Box.createVerticalGlue());

        panelGauche.add(labelBiome1);
        panelGauche.add(labelBiome2);
        panelGauche.add(labelBiome3);
        panelGauche.add(labelBiome4);
        panelGauche.add(labelBiome5);

        panelPrincipal.add(panelGauche, BorderLayout.WEST);
        panelPrincipal.add(panelPlateau, BorderLayout.CENTER);

        add(panelPrincipal);

        // Ajouter un écouteur pour garantir que le panneau du plateau reste un carré
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                Dimension size = panelPlateau.getSize();
                int side = Math.min(size.width, size.height);
                panelPlateau.setPreferredSize(new Dimension(side, side));
                panelPlateau.revalidate();
            }
        });
    }

    // Méthode pour dessiner les biomes sur un bouton
    private void dessinerTuile(Graphics g, Tuile tuile, int width, int height) {
        Graphics2D g2d = (Graphics2D) g.create();
        int halfWidth = width / 2;
        int halfHeight = height / 2;

        // Dessiner le triangle nord
        g2d.setColor(Tuile.getColorForBiome(tuile.getNord()));
        int[] xPointsNord = { 0, halfWidth, width };
        int[] yPointsNord = { 0, halfHeight, 0 };
        g2d.fillPolygon(xPointsNord, yPointsNord, 3);

        // Dessiner le triangle sud
        g2d.setColor(Tuile.getColorForBiome(tuile.getSud()));
        int[] xPointsSud = { 0, halfWidth, width };
        int[] yPointsSud = { height, halfHeight, height };
        g2d.fillPolygon(xPointsSud, yPointsSud, 3);

        // Dessiner le triangle est
        g2d.setColor(Tuile.getColorForBiome(tuile.getEst()));
        int[] xPointsEst = { width, halfWidth, width };
        int[] yPointsEst = { 0, halfHeight, height };
        g2d.fillPolygon(xPointsEst, yPointsEst, 3);

        // Dessiner le triangle ouest
        g2d.setColor(Tuile.getColorForBiome(tuile.getOuest()));
        int[] xPointsOuest = { 0, halfWidth, 0 };
        int[] yPointsOuest = { 0, halfHeight, height };
        g2d.fillPolygon(xPointsOuest, yPointsOuest, 3);

        g2d.dispose();
    }

    // Méthode pour mettre à jour le plateau après placement d'une tuile
    public void updateBoard(int x, int y, Tuile tuile) {
        TileButton bouton = boutons[x][y];
        bouton.setTuile(tuile); // Mettre à jour la tuile sur le bouton
        bouton.setEnabled(false); // Désactiver le bouton pour éviter le placement d'une autre tuile à cette
                                  // position
    }

    public void resetBoard() {
        for (int i = 0; i < taillePlateau; i++) {
            for (int j = 0; j < taillePlateau; j++) {
                boutons[i][j].setTuile(null); // Réinitialiser la tuile sur le bouton
                boutons[i][j].setEnabled(true); // Réactiver le bouton
            }
        }
        repaint();
    }

    public void setScore(int score) {
        labelScore.setText("Score: " + score);
    }

    public void dispose() {
        super.dispose();
        if (musicPlayer != null) {
            musicPlayer.stop();
        }
    }

    public Tuile getTuileCourante() {
        return tuileCourante;
    }

    public void setTuileCourante(Tuile tuile) {
        this.tuileCourante = tuile;
        panelTuileCourante.repaint();
    }

    public void afficherMessage(String message) {
        int result = JOptionPane.showOptionDialog(this, message, "Fin de la partie",
                JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
                null, new Object[] { "Quitter" }, "Quitter");
        if (result == JOptionPane.OK_OPTION) {
            System.exit(0);
        }
    }

    // Classe interne pour représenter un bouton avec une tuile
    private class TileButton extends JButton {
        private Tuile tuile;

        public TileButton() {
            this.tuile = null;
        }

        public void setTuile(Tuile tuile) {
            this.tuile = tuile;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (tuile != null) {
                int width = getWidth();
                int height = getHeight();
                dessinerTuile(g, tuile, width, height);
            }
        }
    }

    // Méthode principale pour tester la fenêtre
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new FenetreDemarrage();
            }
        });
    }
}
