package de.roko.genalogy.downloader.tools;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TileStitcherFixedGrid {

    private static final Pattern TILE_PATTERN = Pattern.compile("tile_(\\d+)_(\\d+)\\.png");

    public static void stitch(File inputFolder, File outputFile) {
        File[] files = inputFolder.listFiles();
        if (files == null || files.length == 0) {
            System.err.println("❌ Keine Tiles im Ordner: " + inputFolder.getAbsolutePath());
            return;
        }

        List<Tile> tiles = new ArrayList<Tile>();
        TreeSet<Integer> colSet = new TreeSet<Integer>();
        TreeSet<Integer> rowSet = new TreeSet<Integer>();

        for (File file : files) {
            Matcher matcher = TILE_PATTERN.matcher(file.getName());
            if (!matcher.matches()) continue;

            int x = Integer.parseInt(matcher.group(1));
            int y = Integer.parseInt(matcher.group(2));

            tiles.add(new Tile(file, x, y));
            colSet.add(x);
            rowSet.add(y);
        }

        if (tiles.isEmpty()) {
            System.err.println("❌ Keine gültigen Tiles gefunden.");
            return;
        }

        List<Integer> colList = new ArrayList<Integer>(colSet);
        List<Integer> rowList = new ArrayList<Integer>(rowSet);

        Map<Integer, Integer> colIndexMap = new HashMap<Integer, Integer>();
        Map<Integer, Integer> rowIndexMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < colList.size(); i++) {
            colIndexMap.put(colList.get(i), i);
        }
        for (int i = 0; i < rowList.size(); i++) {
            rowIndexMap.put(rowList.get(i), i);
        }

        // Beispiel-Kachel lesen
        BufferedImage sampleTile = null;
        for (Tile tile : tiles) {
            try {
                sampleTile = ImageIO.read(tile.file);
                if (sampleTile != null) break;
            } catch (Exception ignored) {}
        }

        if (sampleTile == null) {
            System.err.println("❌ Keine lesbare Kachel gefunden.");
            return;
        }

        int tileWidth = sampleTile.getWidth();
        int tileHeight = sampleTile.getHeight();
        int cols = colList.size();
        int rows = rowList.size();
        int fullWidth = cols * tileWidth;
        int fullHeight = rows * tileHeight;

        System.out.printf("📐 %d×%d Tiles à %dx%d → Bildgröße: %dx%d px%n",
                cols, rows, tileWidth, tileHeight, fullWidth, fullHeight);

        BufferedImage result = new BufferedImage(fullWidth, fullHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = result.createGraphics();

        int count = 0;
        for (Tile tile : tiles) {
            try {
                BufferedImage img = ImageIO.read(tile.file);
                if (img == null) continue;

                int colIndex = colIndexMap.get(tile.x);
                int rowIndex = rowIndexMap.get(tile.y);
                int dx = colIndex * tileWidth;
                int dy = rowIndex * tileHeight;

                g.drawImage(img, dx, dy, null);
                count++;
            } catch (Exception e) {
                System.err.printf("⚠️ Fehler bei %s: %s%n", tile.file.getName(), e.getMessage());
            }
        }

        g.dispose();

        try {
            ImageIO.write(result, "png", outputFile);
            System.out.printf("✅ Gesamtbild gespeichert: %s (%d Tiles verwendet)%n",
                    outputFile.getAbsolutePath(), count);
        } catch (Exception e) {
            System.err.println("❌ Fehler beim Speichern: " + e.getMessage());
        }
    }

    // Hilfsklasse (Java 8-kompatibel, kein record)
    private static class Tile {
        final File file;
        final int x;
        final int y;

        Tile(File file, int x, int y) {
            this.file = file;
            this.x = x;
            this.y = y;
        }
    }
}
