package com.first;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

public class MineSweeper {
    static private GamePanel gPanel;/* 雷区 */
    static private int midtime = 3600, mineNum = 0;/* 倒计时时间以及可用旗子数量 */
    static private JLabel label1, label2;
    static CountDown cd;

    public MineSweeper() {
        JFrame jf = new JFrame("扫雷小游戏");
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setLayout(null);
        jf.setBounds(600, 200, 700, 800);

        label1 = new JLabel("剩余时间：" + formatTime(midtime));
        label1.setBounds(10, 20, 120, 20);
        jf.add(label1);

        label2 = new JLabel("剩余旗子：" + mineNum);
        label2.setBounds(400, 20, 240, 20);
        jf.add(label2);

        JButton resetButt = new JButton("重置");
        resetButt.setMargin(new Insets(0, 0, 0, 0));
        resetButt.setBounds(230, 15, 60, 30);
        resetButt.addActionListener(e -> {
            jf.dispose();
            new MineSweeper();
            midtime = 3600;
        });
        jf.add(resetButt);

        gPanel = new GamePanel(20, 20);
        gPanel.setBounds(40, 100, 600, 600);
        jf.add(gPanel);

        jf.setVisible(true);
    }

    static class CountDown extends Thread {
        @Override
        public void run() {
            super.run();
            while (midtime > 0) {
                try {
                    --midtime;
                    label1.setText("剩余时间：" + formatTime(midtime));
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (midtime == 0) {
                JOptionPane.showMessageDialog(null, "时间已到", "游戏结束", JOptionPane.PLAIN_MESSAGE);
            }
        }
    }

    private static String formatTime(int seconds) {
        int hrs = seconds / 3600;
        int mins = (seconds % 3600) / 60;
        int secs = seconds % 60;
        return String.format("%02d:%02d:%02d", hrs, mins, secs);
    }

    public static void main(String[] args) {
        new MineSweeper();
        cd = new CountDown();
        cd.start();
    }

    public static void setMineNum(int minesCount2) {
        mineNum = minesCount2;
        label2.setText("剩余旗子：" + mineNum);
    }
}

class GamePanel extends JPanel {
    private int rows, cols, minesCount;
    private final int BLOCKWIDTH = 30;
    private final int BLOCKHEIGHT = 30;
    private Buts[][] buts;
    private JLabel[][] jlabel;
    private boolean[][] state;
    private int[][] click;
    private ImageIcon mineIcon;

    public GamePanel(int row, int col) {
        rows = row;
        cols = col;
        minesCount = rows * cols / 10;
        MineSweeper.setMineNum(minesCount);


         try {
             mineIcon = new ImageIcon(ImageIO.read(new File("mine.png")));
         } catch (IOException e) {
             e.printStackTrace();
         }

        // 缩放图标到合适大小
        Image scaledImage = mineIcon.getImage().getScaledInstance(
                BLOCKWIDTH, BLOCKHEIGHT, Image.SCALE_SMOOTH);
        mineIcon = new ImageIcon(scaledImage);

        buts = new Buts[rows][cols];
        jlabel = new JLabel[rows][cols];
        state = new boolean[rows][cols];
        click = new int[rows][cols];

        setLayout(null);
        initButtons();
        initLable();
        buryMines();
        writerNumber();
    }

    private void writerNumber() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (!state[i][j]) {
                    int numbers = 0;
                    for (int r = -1; r < 2; r++) {
                        for (int c = -1; c < 2; c++) {
                            if ((i + r > -1) && (i + r < cols) && (j + c > -1) && (j + c < rows)) {
                                if (state[i + r][j + c]) numbers++;
                            }
                        }
                    }
                    if (numbers > 0) {
                        click[i][j] = 2;
                    }
                    jlabel[i][j].setText(String.valueOf(numbers));
                    jlabel[i][j].setIcon(null); // 确保数字位置不显示图标
                }
            }
        }
    }

    private void initButtons() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                Buts but = new Buts();
                but.i = i;
                but.j = j;
                but.setBounds(BLOCKWIDTH * j, BLOCKHEIGHT * i, BLOCKWIDTH, BLOCKHEIGHT);
                but.setMargin(new Insets(0, 0, 0, 0));

                but.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        if (e.getButton() == MouseEvent.BUTTON1) {
                            openButtons(but);
                        }
                        if (e.getButton() == MouseEvent.BUTTON3) {
                            placeFlag(but);
                        }
                    }
                });
                buts[i][j] = but;
                this.add(buts[i][j]);
            }
        }
    }

    protected void placeFlag(Buts but) {
        if (click[but.i][but.j] != 3) {
            buts[but.i][but.j].setText("旗");
            click[but.i][but.j] = 3;
            minesCount--;
            MineSweeper.setMineNum(minesCount);
        } else {
            buts[but.i][but.j].setText("");
            if (!state[but.i][but.j]) {
                if (Integer.valueOf(jlabel[but.i][but.j].getText()) > 0) {
                    click[but.i][but.j] = 2;
                } else {
                    click[but.i][but.j] = 0;
                }
                minesCount++;
                MineSweeper.setMineNum(minesCount);
            } else {
                click[but.i][but.j] = 0;
            }
        }
        if (minesCount == 0) {
            boolean flag = true;
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if ((click[i][j] != 3) && state[i][j]) {
                        flag = false;
                    }
                }
            }
            MineSweeper.cd.stop();
            JOptionPane.showMessageDialog(null, flag ? "您成功了" : "旗子已经用完", "游戏结束", JOptionPane.PLAIN_MESSAGE);
        }
    }

    protected void openButtons(Buts but) {
        int i = but.i;
        int j = but.j;

        if (state[i][j] && (click[i][j] != 3)) {
            openAllCell();
            MineSweeper.cd.stop();
            JOptionPane.showMessageDialog(null, "您踩到地雷了", "游戏结束", JOptionPane.PLAIN_MESSAGE);
        }

        if (click[i][j] == 2) {
            buts[i][j].setVisible(false);
            jlabel[i][j].setVisible(true);
        }

        if ((click[i][j] == 0) || (click[i][j] == 1)) {
            for (int r = -1; r < 2; r++) {
                for (int c = -1; c < 2; c++) {
                    if ((i + r > -1) && (i + r < cols) && (j + c > -1) && (j + c < rows)
                            && (!state[i + r][j + c])) {

                        if (click[i + r][j + c] == 0) {
                            buts[i + r][j + c].setVisible(false);
                            jlabel[i + r][j + c].setVisible(true);
                            click[i + r][j + c] = 1;
                            openButtons(buts[i + r][j + c]);
                        }

                        if (click[i + r][j + c] == 2) {
                            buts[i + r][j + c].setVisible(false);
                            jlabel[i + r][j + c].setVisible(true);
                        }
                    }
                }
            }
        }
    }

    private void openAllCell() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                buts[i][j].setVisible(false);
                jlabel[i][j].setVisible(true);
                if (state[i][j]) {
                    jlabel[i][j].setIcon(mineIcon);
                }
                click[i][j] = 1;
            }
        }
    }

    private void initLable() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                JLabel l = new JLabel("", JLabel.CENTER);
                l.setBounds(j * BLOCKWIDTH, i * BLOCKHEIGHT, BLOCKWIDTH, BLOCKHEIGHT);
                l.setBorder(BorderFactory.createLineBorder(Color.gray));
                l.setOpaque(true);
                l.setBackground(Color.lightGray);
                l.setHorizontalTextPosition(SwingConstants.CENTER);
                l.setVerticalTextPosition(SwingConstants.CENTER);
                this.add(l);
                jlabel[i][j] = l;
                l.setVisible(false);
            }
        }
    }

    private void buryMines() {
        for (int i = 0; i < minesCount; i++) {
            int x = (int) (Math.random() * rows);
            int y = (int) (Math.random() * cols);
            if (!state[x][y]) {
                state[x][y] = true;
                jlabel[x][y].setIcon(mineIcon);
                jlabel[x][y].setText("");
            } else {
                i--;
            }
        }
    }
}

class Buts extends JButton {
    public int i, j;
}