"""Die aktuelle Minimap als Vorlage sichern - aber nur, wenn sie taugt.

Aufrufen, nachdem der Karten-Installer von TibiaMaps.io bei
*geschlossenem* Client durchgelaufen ist. Danach stellt jeder
Client-Start die Karte automatisch wieder her (siehe
src/utils/minimap.py).

Vor dem Sichern wird geprueft, wie vollstaendig die Karte ueberhaupt ist
- gemessen an den Referenzkarten des Bots, die den ganzen bekannten
Weltausschnitt abdecken. Eine lueckenhafte Karte als Vorlage zu sichern
waere schlimmer als gar keine Vorlage: sie wuerde die Luecke bei jedem
Start neu herstellen.
"""

import argparse
import re
import sys
from pathlib import Path

repo = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(repo))

import cv2
import numpy as np

from src.repositories.radar.config import floorsImgs
from src.utils.minimap import erstelleVorlage, minimapOrdner, vorlageOrdner


WELT_X, WELT_Y = 31744, 30976
KACHEL = 256
NAME = re.compile(r'Minimap_Color_(\d+)_(\d+)_(\d+)\.png', re.IGNORECASE)


def vollstaendigkeit(ordner: Path):
    """Anteil der erkundeten Felder, gemessen an den Referenzkarten."""
    erkundet = bekannt = 0
    luecken = []
    for pfad in sorted(ordner.glob('Minimap_Color_*.png')):
        treffer = NAME.match(pfad.name)
        if not treffer:
            continue
        x, y, etage = (int(treffer.group(index)) for index in (1, 2, 3))
        px, py = x - WELT_X, y - WELT_Y
        referenzkarte = floorsImgs[etage]
        if not (0 <= px <= referenzkarte.shape[1] - KACHEL
                and 0 <= py <= referenzkarte.shape[0] - KACHEL):
            continue
        kachel = cv2.imread(str(pfad), cv2.IMREAD_GRAYSCALE)
        if kachel is None or kachel.shape != (KACHEL, KACHEL):
            continue
        referenz = referenzkarte[py:py + KACHEL, px:px + KACHEL]
        hat = int(np.count_nonzero(kachel))
        soll = int(np.count_nonzero(referenz))
        if soll == 0:
            continue
        erkundet += hat
        bekannt += soll
        if hat < soll * 0.999:
            luecken.append((etage, x, y, hat, soll))
    return erkundet, bekannt, luecken


def main() -> int:
    zerleger = argparse.ArgumentParser(description=__doc__)
    zerleger.add_argument(
        '--trotzdem', action='store_true',
        help='auch eine lueckenhafte Karte sichern')
    argumente = zerleger.parse_args()

    quelle = minimapOrdner()
    if not quelle.is_dir():
        print(f'Minimap-Ordner fehlt: {quelle}')
        return 1

    erkundet, bekannt, luecken = vollstaendigkeit(quelle)
    if bekannt == 0:
        print(f'Keine auswertbaren Kacheln unter {quelle}')
        return 1
    anteil = erkundet / bekannt
    print(f'Karte: {anteil * 100:.2f} % erkundet '
          f'({erkundet:,} von {bekannt:,} Feldern)')
    for etage, x, y, hat, soll in luecken[:20]:
        print(f'  Luecke  Etage {etage}  Block {x},{y}  '
              f'{hat:,} von {soll:,} = {hat / soll * 100:.1f} %')
    if len(luecken) > 20:
        print(f'  ... und {len(luecken) - 20} weitere')

    if luecken and not argumente.trotzdem:
        print('\nNicht gesichert. Erst den Karten-Installer bei '
              'geschlossenem Client laufen lassen, dann erneut aufrufen '
              '(oder --trotzdem verwenden).')
        return 2

    anzahl = erstelleVorlage(quelle)
    print(f'\nVorlage gesichert: {anzahl} Kacheln nach {vorlageOrdner()}')
    return 0


if __name__ == '__main__':
    raise SystemExit(main())
