import gradio as gr
from roboflow import Roboflow
import supervision as sv
import cv2
from ultralytics import YOLOv10 
import spaces
from huggingface_hub import hf_hub_download


def download_models(model_id):
    hf_hub_download("faruqaziz/deteksi-beras", filename=f"{model_id}", local_dir=f"./")
    return f"./{model_id}"
    
box_annotator = sv.BoxAnnotator()
category_dict = {0: 'arborio', 1: 'basmati', 2: 'ipsala', 3: 'jasmine', 4: 'karacadag'}


@spaces.GPU(duration=200)
def yolov10_inference(image, model_id, image_size, conf_threshold, iou_threshold):
    model_path = download_models(model_id)
    model = YOLOv10(model_path)
    results = model(source=image, imgsz=image_size, iou=iou_threshold, conf=conf_threshold, verbose=False)[0]
    detections = sv.Detections.from_ultralytics(results)
    
    labels = [
        f"{category_dict[class_id]} {confidence:.2f}"
        for class_id, confidence in zip(detections.class_id, detections.confidence)
    ]
    annotated_image = box_annotator.annotate(image, detections=detections, labels=labels)

    return annotated_image

def app():
    with gr.Blocks():
        with gr.Row():
            with gr.Column():
                image = gr.Image(type="numpy", label="Image")
                
                model_id = gr.Dropdown(
                    label="Model",
                    choices=[
                        "best.pt",
                        "last.pt",
                    ],
                    value="best.pt",
                )
                image_size = gr.Slider(
                    label="Image Size",
                    minimum=320,
                    maximum=1280,
                    step=32,
                    value=640,
                )
                conf_threshold = gr.Slider(
                    label="Confidence Threshold",
                    minimum=0.1,
                    maximum=1.0,
                    step=0.1,
                    value=0.25,
                )
                iou_threshold = gr.Slider(
                    label="IoU Threshold",
                    minimum=0.1,
                    maximum=1.0,
                    step=0.1,
                    value=0.45,
                )
                yolov10_infer = gr.Button(value="Detect Objects")

            with gr.Column():
                output_image = gr.Image(type="numpy", label="Annotated Image")

        yolov10_infer.click(
            fn=yolov10_inference,
            inputs=[
                image,
                model_id,
                image_size,
                conf_threshold,
                iou_threshold,
            ],
            outputs=[output_image],
        )

gradio_app = gr.Blocks()
with gradio_app:
    gr.HTML(
        """
    <h1 style='text-align: center'>
    YOLOv10: Real-Time End-to-End Object Detection
    </h1>
    """)
    gr.HTML(
        """
        <h3 style='text-align: center'>
        Baru testing!
        </h3>
        """)
    with gr.Row():
        with gr.Column():
            app()

gradio_app.launch(debug=True)