import re
import sys
import zipfile
from pathlib import Path

import cv2
import numpy as np


ORIGIN_X = 31744
ORIGIN_Y = 30976
WIDTH = 2560
HEIGHT = 2048
TILE_PATTERN = re.compile(r"Minimap_Color_(\d+)_(\d+)_(\d+)\.png$")


def build(zip_path: Path, output_dir: Path) -> None:
    output_dir.mkdir(parents=True, exist_ok=True)
    floors = [np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8) for _ in range(16)]
    counts = [0] * 16

    with zipfile.ZipFile(zip_path) as archive:
        for name in archive.namelist():
            match = TILE_PATTERN.search(name)
            if match is None:
                continue
            world_x, world_y, floor = map(int, match.groups())
            if floor >= len(floors):
                continue
            tile = cv2.imdecode(
                np.frombuffer(archive.read(name), dtype=np.uint8),
                cv2.IMREAD_COLOR,
            )
            if tile is None:
                raise ValueError(f"Ungültiges Minimap-Bild: {name}")
            x = world_x - ORIGIN_X
            y = world_y - ORIGIN_Y
            x0, y0 = max(x, 0), max(y, 0)
            x1, y1 = min(x + tile.shape[1], WIDTH), min(y + tile.shape[0], HEIGHT)
            if x0 >= x1 or y0 >= y1:
                continue
            floors[floor][y0:y1, x0:x1] = tile[
                y0 - y:y1 - y,
                x0 - x:x1 - x,
            ]
            counts[floor] += 1

    for floor, image in enumerate(floors):
        if counts[floor] == 0:
            raise ValueError(f"Keine Minimap-Kacheln für Etage {floor}")
        destination = output_dir / f"floor-{floor}.png"
        if not cv2.imwrite(str(destination), image):
            raise OSError(f"Minimap konnte nicht gespeichert werden: {destination}")
        print(f"Etage {floor}: {counts[floor]} Kacheln")


if __name__ == "__main__":
    if len(sys.argv) != 3:
        raise SystemExit("Nutzung: Build-Current-Minimap.py <minimap.zip> <ausgabe>")
    build(Path(sys.argv[1]), Path(sys.argv[2]))
