"""
Pre-label images using an existing YOLO model.
Generates .txt labels for unlabeled images so the annotator can load them for review.

Usage:
    python prelabel.py [image_dir] [--model boss-v1] [--conf 0.20]
"""
import argparse
import glob
import os

def run_prelabel(args):
    """Run pre-labeling. Called from main() or manage.py."""
    img_dir = os.path.abspath(args.img_dir)
    model_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "models", f"{args.model}.pt")

    if not os.path.exists(model_path):
        print(f"Model not found: {model_path}")
        return

    from ultralytics import YOLO
    model = YOLO(model_path)

    extensions = ("*.jpg", "*.jpeg", "*.png")
    files = []
    for ext in extensions:
        files.extend(glob.glob(os.path.join(img_dir, ext)))
    files.sort()

    # Only process unlabeled images
    unlabeled = []
    for f in files:
        label_path = os.path.splitext(f)[0] + ".txt"
        if not os.path.exists(label_path):
            unlabeled.append(f)

    print(f"Found {len(files)} images, {len(files) - len(unlabeled)} already labeled, {len(unlabeled)} to pre-label")

    if not unlabeled:
        print("All images already have labels!")
        return

    labeled = 0
    skipped = 0
    for filepath in unlabeled:
        results = model(filepath, conf=args.conf, verbose=False)
        boxes = results[0].boxes

        if len(boxes) == 0:
            skipped += 1
            continue

        label_path = os.path.splitext(filepath)[0] + ".txt"
        with open(label_path, "w") as f:
            for box in boxes:
                cls = int(box.cls[0])
                xywhn = box.xywhn[0]  # normalized center x, y, w, h
                cx, cy, w, h = xywhn.tolist()
                f.write(f"{cls} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}\n")

        labeled += 1
        fname = os.path.basename(filepath)
        conf = boxes.conf[0].item()
        print(f"  {fname}: {len(boxes)} box(es), best conf={conf:.2f}")

    print(f"\nPre-labeled {labeled} images, skipped {skipped} (no detections)")


def main():
    parser = argparse.ArgumentParser(description="Pre-label images with YOLO model")
    parser.add_argument("img_dir", nargs="?", default="../../training-data/kulemak/raw")
    parser.add_argument("--model", default="boss-kulemak", help="Model name in models/")
    parser.add_argument("--conf", type=float, default=0.20, help="Confidence threshold")
    args = parser.parse_args()
    run_prelabel(args)

if __name__ == "__main__":
    main()
