"""BotLab: OpenCV sobre imágenes, nunca sobre nombres de objetos del simulador.
Uso: python vision.py captura.png --destino 3
Instalación: python -m pip install opencv-python-headless==4.12.0.88
Importa entrenamiento.json en la pestaña Cámara. Repite con los cinco IDs.
"""
import argparse,json,random
from pathlib import Path
import cv2
import numpy as np
DICTIONARY=cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50)

def detect(image):
    gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) if image.ndim==3 else image
    corners,ids,_=cv2.aruco.ArucoDetector(DICTIONARY).detectMarkers(gray)
    return [] if ids is None else [{'id':int(i),'corners':c.reshape(4,2).tolist()} for i,c in zip(ids.flatten(),corners)]

def generate():
    ids=random.sample(range(50),5);destinations=random.sample(range(5),5)
    return {'dictionary':'DICT_4X4_50','markers':[{'id':i,'destination':d,'pixels':cv2.aruco.generateImageMarker(DICTIONARY,i,120).tolist()} for i,d in zip(ids,destinations)]}

if __name__=='__main__':
    parser=argparse.ArgumentParser(description=__doc__)
    parser.add_argument('image',nargs='?');parser.add_argument('--destino',type=int,choices=range(1,6))
    parser.add_argument('--mapa',default='entrenamiento.json');parser.add_argument('--generar',action='store_true')
    args=parser.parse_args()
    if args.generar:
        for item in generate()['markers']:
            image=np.pad(np.array(item['pixels'],dtype=np.uint8),15,constant_values=255)
            cv2.imwrite(f"aruco-{item['id']}.png",image)
        print('Cinco marcadores distintos generados.');raise SystemExit
    if not args.image:parser.error('Descarga una captura de la cámara y proporciona su ruta.')
    image=cv2.imread(args.image)
    if image is None:parser.error('No se pudo leer la imagen.')
    found=detect(image);print(json.dumps(found,indent=2))
    if args.destino:
        if len(found)!=1:parser.error('Encuadra exactamente un marcador para enseñarle un destino.')
        path=Path(args.mapa);mapping=json.loads(path.read_text()) if path.exists() else {}
        mapping[str(found[0]['id'])]=args.destino
        path.write_text(json.dumps(mapping,indent=2));print(f'Guardado en {path}. Importa este JSON en BotLab.')
