package gtanks.captcha;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;

public class CaptchaGenerator {
    private static final int WIDTH = 281;
    private static final int HEIGHT = 50;
    private static final Color BACKGROUND_COLOR = Color.decode("#665b67");
    private static final String CAPTCHA_TEXT_FONT_NAME = "Times New Roman";
    private static final int CAPTCHA_TEXT_FONT_SIZE = 40;
    private static final int CAPTCHA_TEXT_LENGTH = 6;

    private static Random random = new Random();

    public static Captcha generateCaptcha() throws IOException {
        String captchaText = getRandomCaptchaText(CAPTCHA_TEXT_LENGTH);
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

        Graphics2D graphics2D = image.createGraphics();
        graphics2D.setColor(BACKGROUND_COLOR);
        graphics2D.fillRect(0, 0, WIDTH, HEIGHT);

        double minIntensity = 0.2;
        double maxIntensity = 0.5;
        double noiseDensity = minIntensity + Math.random() * (maxIntensity - minIntensity);
        int noiseAmount = (int) (WIDTH * HEIGHT * noiseDensity);

        for (int i = 0; i < noiseAmount; i++) {
            graphics2D.setColor(getRandomColor());
            int xPosNoise = (int) (Math.random() * WIDTH);
            int yPosNoise = (int) (Math.random() * HEIGHT);
            graphics2D.fillRect(xPosNoise, yPosNoise, 1, 1);
        }

        // Drawing random lines
        int lineAmount = 2;
        for (int i = 0; i < lineAmount; i++) {
            graphics2D.setColor(Color.BLACK);
            int x1 = random.nextInt(WIDTH);
            int y1 = random.nextInt(HEIGHT);
            int x2 = random.nextInt(WIDTH);
            int y2 = random.nextInt(HEIGHT);
            graphics2D.setStroke(new BasicStroke(random.nextInt(3) + 1));
            graphics2D.draw(new Line2D.Double(x1, y1, x2, y2));
        }

        // Drawing captcha text
        Font captchaTextFont = new Font(CAPTCHA_TEXT_FONT_NAME, Font.BOLD, CAPTCHA_TEXT_FONT_SIZE);
        FontMetrics fontMetrics = graphics2D.getFontMetrics(captchaTextFont);
        int totalWidth = fontMetrics.stringWidth(captchaText);
        int startX = (WIDTH - totalWidth) / 2;
        int startY = (HEIGHT - captchaTextFont.getSize()) / 2 + fontMetrics.getAscent();

        graphics2D.setFont(captchaTextFont);

        // Drawing captcha text characters with random offset
        for (int i = 0; i < CAPTCHA_TEXT_LENGTH; i++) {
            graphics2D.setColor(Color.BLACK);

            int xPos = startX + fontMetrics.stringWidth(captchaText.substring(0, i));
            int yPos = startY;

            // Generating random offset for each character
            int xOffset = random.nextInt(11) - 5; // Offset from -5 to 5
            xPos += xOffset;

            graphics2D.drawString(String.valueOf(captchaText.charAt(i)), xPos, yPos);
        }

        graphics2D.dispose();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        byte[] captchaImageBuffer = baos.toByteArray();

        return new Captcha(captchaImageBuffer, captchaText);
    }

    private static Color getRandomColor() {
        String letters = "0123456789ABCDEF";
        StringBuilder color = new StringBuilder("#");
        for (int i = 0; i < 6; i++) {
            color.append(letters.charAt((int) (Math.random() * 16)));
        }
        return Color.decode(color.toString());
    }

    private static String getRandomCaptchaText(int length) {
        String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }

        return sb.toString();
    }

    public static class Captcha {
        private byte[] image;
        private String text;

        public Captcha(byte[] image, String text) {
            this.image = image;
            this.text = text;
        }

        public byte[] getImage() {
            return image;
        }

        public String getText() {
            return text;
        }
    }
}
 сделай чтобы линии были всегда относительно к тексту капчи