from src.infrastructure.vision_service import VertexVisionService
from src.infrastructure.repository import MongoPalmOilRepository
from src.domain.models import PalmOilBunch

class AnalyzeBunchUseCase:
    def __init__(self, vision_service: VertexVisionService, repo: MongoPalmOilRepository):
        self.vision_service = vision_service
        self.repo = repo

    def execute(self, image_path: str, yolo_result: dict):
        # 1. Get the visual fingerprint
        vector = self.vision_service.get_image_embedding(image_path)

        # 2. Resize and Convert Image to Base64 String via Vision Service
        encoded_string = self.vision_service.encode_image_to_base64(image_path)

        # 3. Create the Domain Entity with Image Data
        bunch = PalmOilBunch(
            ripeness_class=yolo_result['class'],
            confidence=yolo_result['confidence'],
            embedding=vector,
            box=yolo_result['box'],
            image_data=encoded_string
        )

        # 4. Persist to MongoDB
        record_id = self.repo.save(bunch)
        return record_id

class AnalyzeBatchUseCase:
    def __init__(self, vision_service: VertexVisionService, repo: MongoPalmOilRepository):
        self.vision_service = vision_service
        self.repo = repo

    def execute(self, image_results: list):
        """
        image_results: List of dicts {'path': str, 'yolo': dict}
        """
        processed_bunches = []
        
        for item in image_results:
            # 1. Vectorize
            vector = self.vision_service.get_image_embedding(item['path'])
            # 2. Encode Image
            img_b64 = self.vision_service.encode_image_to_base64(item['path'])
            
            # 3. Create Domain Model
            bunch = PalmOilBunch(
                ripeness_class=item['yolo']['class'],
                confidence=item['yolo']['confidence'],
                embedding=vector,
                box=item['yolo']['box'],
                image_data=img_b64
            )
            processed_bunches.append(bunch)

        # 4. Bulk Save
        return self.repo.save_many(processed_bunches)

class SearchSimilarUseCase:
    def __init__(self, vision_service: VertexVisionService, repo: MongoPalmOilRepository):
        self.vision_service = vision_service
        self.repo = repo

    def execute(self, image_path: str = None, text_query: str = None, limit: int = 3):
        """Supports both visual similarity and natural language search."""
        query_vector = None
        
        if image_path:
            query_vector = self.vision_service.get_image_embedding(image_path)
        elif text_query:
            query_vector = self.vision_service.get_text_embedding(text_query)
        
        if not query_vector:
            raise ValueError("Must provide either an image or a text query.")

        return self.repo.vector_search(query_vector, limit)
