"""
Training script for YOLO enemy/boss detection model.

Usage:
    python train.py --data path/to/data.yaml --epochs 200
    python train.py --data path/to/data.yaml --model yolo11m --imgsz 1280 --epochs 300

Expects YOLO-format dataset with data.yaml pointing to train/val image directories.
Export from Roboflow in "YOLOv11" format.
"""

import argparse
import glob
import os


def run_training(args):
    """Run YOLO training. Called from main() or manage.py."""
    from ultralytics import YOLO

    model = YOLO(f"{args.model}.pt")

    model.train(
        data=args.data,
        epochs=args.epochs,
        imgsz=args.imgsz,
        batch=args.batch,
        device=args.device,
        name=args.name,
        patience=30,

        # Learning rate (fine-tuning pretrained, not from scratch)
        lr0=0.001,
        lrf=0.01,
        cos_lr=True,
        warmup_epochs=5,
        weight_decay=0.001,

        # Augmentation tuned for boss glow/morph effects
        hsv_h=0.03,
        hsv_s=0.8,
        hsv_v=0.6,
        scale=0.7,
        translate=0.2,
        degrees=5.0,
        mixup=0.15,
        close_mosaic=15,
        erasing=0.3,

        workers=0,          # avoid multiprocessing paging file issues on Windows
        save=True,
        save_period=10,
        plots=True,
        verbose=True,
    )

    # Find best.pt — try the trainer's save_dir first, then scan runs/detect/
    best_path = None
    save_dir = getattr(model.trainer, "save_dir", None)
    if save_dir:
        candidate = os.path.join(str(save_dir), "weights", "best.pt")
        if os.path.exists(candidate):
            best_path = candidate
    if not best_path:
        run_base = os.path.join("runs", "detect")
        candidates = sorted(glob.glob(os.path.join(run_base, f"{args.name}*", "weights", "best.pt")))
        best_path = candidates[-1] if candidates else os.path.join(run_base, args.name, "weights", "best.pt")

    output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "models")
    os.makedirs(output_dir, exist_ok=True)

    # If boss is set (from manage.py), deploy as boss-{boss}.pt; otherwise use run name
    boss = getattr(args, "boss", None)
    model_filename = f"boss-{boss}.pt" if boss else f"{args.name}.pt"
    output_path = os.path.join(output_dir, model_filename)
    if os.path.exists(best_path):
        import shutil
        shutil.copy2(best_path, output_path)
        print(f"\nBest model copied to: {output_path}")
    else:
        print(f"\nWarning: {best_path} not found -- check training output")


def main():
    parser = argparse.ArgumentParser(description="Train YOLO enemy/boss detector")
    parser.add_argument("--data", required=True, help="Path to data.yaml")
    parser.add_argument("--model", default="yolo11s", help="YOLO model variant (yolo11n, yolo11s, yolo11m)")
    parser.add_argument("--epochs", type=int, default=200, help="Training epochs")
    parser.add_argument("--imgsz", type=int, default=1280, help="Image size")
    parser.add_argument("--batch", type=int, default=8, help="Batch size")
    parser.add_argument("--device", default="0", help="CUDA device (0, cpu)")
    parser.add_argument("--name", default="enemy-v1", help="Run name")
    args = parser.parse_args()
    run_training(args)


if __name__ == "__main__":
    main()
