import cv2 
from pathlib import Path 
from typing import List ,Dict ,Optional 

from .config import (
CV_DIR ,
ULTRALYTICS_AVAILABLE ,
)
from .detectors import YOLO26Detector ,HybridLogoDetector 

def start_scanner (model_path :Optional [str ]=None ,
model_size :str ="nano",
logo_model_path :Optional [str ]=None ,
use_gui :bool =True ,
use_tracking :bool =False ,
hybrid_mode :bool =False ):
    print ("="*60 )
    if hybrid_mode :
        print ("YOLO26 Hybrid Scanner (COCO + Logos)")
    else :
        print ("YOLO26 Object Detection Scanner")
    print ("="*60 )

    detector =None 

    if hybrid_mode and ULTRALYTICS_AVAILABLE :
        try :
            detector =HybridLogoDetector (
            coco_model_size =model_size ,
            logo_model_path =logo_model_path ,
            conf_threshold =0.25 ,
            device ="auto"
            )
        except Exception as e :
            print (f"Hybrid detector failed: {e }")
            hybrid_mode =False 

    if detector is None and ULTRALYTICS_AVAILABLE :
        try :
            detector =YOLO26Detector (
            model_size =model_size ,
            model_path =model_path ,
            conf_threshold =0.25 ,
            device ="auto"
            )
        except Exception as e :
            print (f"YOLO26 failed: {e }")

    if detector is None :
        print ("Error: No detector available.")
        return 

    cap =cv2 .VideoCapture (0 )
    if not cap .isOpened ():
        print ("Error: Could not access camera.")
        return 

    width =int (cap .get (cv2 .CAP_PROP_FRAME_WIDTH ))
    height =int (cap .get (cv2 .CAP_PROP_FRAME_HEIGHT ))
    fps =cap .get (cv2 .CAP_PROP_FPS )or 30.0 

    writer =None 
    output_path =CV_DIR /"output.mp4"

    print (f"Camera: {width }x{height } @ {fps :.1f}fps")
    print ("Controls: q=quit | s=screenshot | t=tracking")
    if hybrid_mode :
        print ("          o=objects | l=logos | b=both")

    frame_count =0 
    detect_objects_flag =True 
    detect_logos_flag =True 

    try :
        while True :
            ret ,frame =cap .read ()
            if not ret :
                break 

            frame_count +=1 

            if hybrid_mode and isinstance (detector ,HybridLogoDetector ):
                detections =detector .detect (
                frame ,
                detect_objects =detect_objects_flag ,
                detect_logos =detect_logos_flag 
                )
            elif use_tracking and isinstance (detector ,YOLO26Detector ):
                detections =detector .detect_and_track (frame )
            else :
                detections =detector .detect (frame )

            result_frame =detector .draw_detections (frame ,detections )

            mode_str ="HYBRID"if hybrid_mode else ("TRACK"if use_tracking else "DETECT")
            cv2 .putText (result_frame ,f"{mode_str } | {len (detections )} objects",
            (10 ,30 ),cv2 .FONT_HERSHEY_SIMPLEX ,0.6 ,(0 ,255 ,0 ),2 )

            if use_gui :
                try :
                    cv2 .imshow ('YOLO26 Scanner',result_frame )
                    key =cv2 .waitKey (1 )&0xFF 
                    if key ==ord ('q'):
                        break 
                    elif key ==ord ('s'):
                        path =CV_DIR /f"screenshot_{frame_count }.jpg"
                        cv2 .imwrite (str (path ),result_frame )
                        print (f"Saved: {path }")
                    elif key ==ord ('t')and isinstance (detector ,YOLO26Detector ):
                        use_tracking =not use_tracking 
                    elif key ==ord ('o')and hybrid_mode :
                        detect_objects_flag ,detect_logos_flag =True ,False 
                    elif key ==ord ('l')and hybrid_mode :
                        detect_objects_flag ,detect_logos_flag =False ,True 
                    elif key ==ord ('b')and hybrid_mode :
                        detect_objects_flag ,detect_logos_flag =True ,True 
                except cv2 .error :
                    use_gui =False 
                    writer =cv2 .VideoWriter (
                    str (output_path ),cv2 .VideoWriter_fourcc (*'mp4v'),
                    fps ,(width ,height )
                    )

            if not use_gui and writer :
                writer .write (result_frame )

    except KeyboardInterrupt :
        print ("Stopping...")
    finally :
        cap .release ()
        if writer :
            writer .release ()
        cv2 .destroyAllWindows ()

def detect_objects (image_path :str ,
model_size :str ="nano",
conf_threshold :float =0.25 ,
save_output :bool =True ,
hybrid_mode :bool =False )->List [Dict ]:
    if not ULTRALYTICS_AVAILABLE :
        raise RuntimeError ("Ultralytics not installed")

    if hybrid_mode :
        detector =HybridLogoDetector (
        coco_model_size =model_size ,
        conf_threshold =conf_threshold 
        )
    else :
        detector =YOLO26Detector (
        model_size =model_size ,
        conf_threshold =conf_threshold 
        )

    image =cv2 .imread (image_path )
    if image is None :
        raise ValueError (f"Could not load: {image_path }")

    detections =detector .detect (image )

    if save_output :
        result =detector .draw_detections (image ,detections )
        output =Path (image_path ).stem +"_detected.jpg"
        cv2 .imwrite (output ,result )
        print (f"Saved: {output }")

    return detections 
