package fr.iut_fbleau.HexGame;

import fr.iut_fbleau.GameAPI.Player;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Path2D;

/**
 * Panel Swing qui dessine un plateau Hex en hexagones et gère les clics.
 *
 * Grille "flat-top" (hexagones à sommet plat en haut),
 * avec décalage vertical d'une demi-hauteur une colonne sur deux.
 */
public class HexPanel extends JPanel {

    private final HexBoard board;
    private final JLabel statusLabel;

    // Rayon (distance centre -> sommet)
    private final int s = 26;
    private final int margin = 40;
    // pointy-top : largeur = sqrt(3)*s, hauteur = 2*s
    private final double hexW = Math.sqrt(3) * s;
    private final double hexVStep = 1.5 * s; // distance verticale entre centres


    private Shape[][] hexShapes;

    public HexPanel(HexBoard board, JLabel statusLabel) {
        this.board = board;
        this.statusLabel = statusLabel;
        this.hexShapes = new Shape[board.getSize()][board.getSize()];

        setBackground(Color.WHITE);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                handleClick(e.getX(), e.getY());
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        int n = board.getSize();

        // largeur : n * hexW + décalage max (hexW/2) + marges
        int w = margin * 2 + (int) (n * hexW + hexW / 2);

        // hauteur : (n-1)*1.5*s + 2*s + marges
        int h = margin * 2 + (int) ((n - 1) * hexVStep + 2 * s);

        return new Dimension(w, h);
    }


    private void handleClick(int x, int y) {
        if (board.isGameOver()) return;

        int n = board.getSize();
        for (int row = 0; row < n; row++) {
            for (int col = 0; col < n; col++) {
                Shape sh = hexShapes[row][col];
                if (sh != null && sh.contains(x, y)) {
                    HexPly ply = new HexPly(board.getCurrentPlayer(), row, col);
                    if (board.isLegal(ply)) {
                        board.doPly(ply);
                        HexFrame.updateStatus(board, statusLabel);
                        repaint();
                    } else {
                        Toolkit.getDefaultToolkit().beep();
                    }
                    return;
                }
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Bordures objectifs (bleu gauche/droite, rouge haut/bas)
        drawGoalBorders(g2);

        int n = board.getSize();

        // IMPORTANT : boucles cohérentes -> row puis col
        for (int row = 0; row < n; row++) {
            for (int col = 0; col < n; col++) {

                Shape hex = createHexShape(row, col);
                hexShapes[row][col] = hex;

                Player p = board.getCellPlayer(row, col);
                g2.setColor(colorForCell(p));
                g2.fill(hex);

                g2.setColor(new Color(120, 120, 120));
                g2.setStroke(new BasicStroke(1.2f));
                g2.draw(hex);
            }
        }

        g2.dispose();
    }

    private Color colorForCell(Player p) {
        if (p == Player.PLAYER1) return new Color(30, 90, 160); // bleu
        if (p == Player.PLAYER2) return new Color(220, 50, 50); // rouge
        return new Color(190, 190, 190); // gris
    }

    /**
    * Pointy-top + décalage par ligne :
    *
    * centreX = margin + hexW/2 + col*hexW + (row%2)*(hexW/2)
    * centreY = margin + s + row*(1.5*s)
    */
    private Shape createHexShape(int row, int col) {
        double cx = margin + (hexW / 2.0) + col * hexW + ((row % 2) * (hexW / 2.0));
        double cy = margin + s + row * hexVStep;

        Path2D.Double path = new Path2D.Double();
        for (int i = 0; i < 6; i++) {
            double angle = Math.toRadians(i * 60); // pointy-top
            double x = cx + s * Math.cos(angle);
            double y = cy + s * Math.sin(angle);
            if (i == 0) path.moveTo(x, y);
            else path.lineTo(x, y);
        }
        path.closePath();
        return path;
    }


    private void drawGoalBorders(Graphics2D g2) {
        int n = board.getSize();

        double leftX = margin - 12;
        double rightX = margin + (hexW / 2.0) + (n - 1) * hexW + (hexW / 2.0) + (hexW / 2.0) + 12;
        // explication: largeur n colonnes + potentiel décalage d'une demi-largeur

        double topY = margin - 12;
        double bottomY = margin + s + (n - 1) * hexVStep + s + 12;

        g2.setStroke(new BasicStroke(6f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));

        // Bleu: gauche / droite (objectif PLAYER1)
        g2.setColor(new Color(30, 90, 160));
        g2.drawLine((int) leftX, (int) topY, (int) leftX, (int) bottomY);
        g2.drawLine((int) rightX, (int) topY, (int) rightX, (int) bottomY);

        // Rouge: haut / bas (objectif PLAYER2)
        g2.setColor(new Color(220, 50, 50));
        g2.drawLine((int) leftX, (int) topY, (int) rightX, (int) topY);
        g2.drawLine((int) leftX, (int) bottomY, (int) rightX, (int) bottomY);
    }
}
