"""Pipeline principal pour génération d'annonces publicitaires."""

from typing import Optional

from loops.generators.concept import NewAdConcept
from loops.generators.prompt import PromptNanobanana
from loops.generators.visual import NewAdVisual
from loops.processors.image import EncodedImage
from loops.processors.ocr import RawAdVisual


class AdGenerationPipeline:
    """Pipeline complet de génération d'annonces publicitaires."""
    
    def __init__(
        self,
        brand_brief: str,
        inspiration_path: str,
        product_image_path: str,
        font_path: Optional[str] = None,
    ):
        """
        Initialise le pipeline.
        
        Args:
            brand_brief: String avec le contenu du brief produit
            inspiration_path: Chemin vers l'annonce d'inspiration (JPEG/PNG)
            product_image_path: Chemin vers l'image produit (PNG/JPEG)
            font_path: Chemin vers la police (optionnel, pour correction OCR)
        """
        self.brand_brief = brand_brief
        self.inspiration_path = inspiration_path
        self.product_image_path = product_image_path
        self.font_path = font_path
        
    def generate(
        self,
        fix_text: bool = True,
    ) -> dict:
        """
        Exécute le pipeline complet.
        
        Args:
            fix_text: Si True, corrige le texte via OCR
            
        Returns:
            Dict avec:
                - concept: str - Concept généré
                - prompt: str - Prompt pour nanobanana
                - raw_image: bytes - Image brute (prête pour Cloudinary)
                - fixed_image: bytes | None - Image corrigée (prête pour Cloudinary)
        """
        results = {}
        
        # Step 1: Generate concept
        print("Step 1: Generating ad concept...")
        concept_generator = NewAdConcept(self.brand_brief)
        concept = concept_generator.generate_from(self.inspiration_path)
        results["concept"] = concept
        print(f"✓ Concept generated")
        
        # Step 2: Generate prompt for nanobanana
        print("Step 2: Generating prompt for nanobanana...")
        prompt_generator = PromptNanobanana()
        prompt = prompt_generator.generate_from(concept)
        results["prompt"] = prompt
        print(f"✓ Prompt generated")
        
        # Step 3: Generate new ad visual
        print("Step 3: Generating new ad visual...")
        visual_generator = NewAdVisual(self.product_image_path)
        new_ad_visual = visual_generator.generate_following(prompt)
        
        if not isinstance(new_ad_visual, list):
            new_ad_visual = [new_ad_visual]
        
        # Filter out non-image responses
        image_responses = []
        for o in new_ad_visual:
            if isinstance(o, dict):
                # Check for image_url format
                if "image_url" in o:
                    image_responses.append(o)
                # Check for direct image content
                elif "type" in o and o.get("type") == "image_url":
                    image_responses.append(o)
                # Check for nested structure
                elif "content" in o and isinstance(o["content"], dict) and "image_url" in o["content"]:
                    image_responses.append(o["content"])
        
        if len(image_responses) == 0:
            raise ValueError("No image response found in Gemini output. Response format may have changed.")
        
        image_response = image_responses[0]
        
        # Extract image_url
        if "image_url" in image_response:
            image_url = image_response["image_url"]
            if isinstance(image_url, dict) and "url" in image_url:
                image_url = image_url["url"]
        else:
            raise ValueError("Could not extract image URL from Gemini response")
        
        if "," in image_url:
            image_content = image_url.split(",")[1]
        elif "base64," in image_url:
            image_content = image_url.split("base64,")[1]
        else:
            image_content = image_url
        
        encoded_image = EncodedImage(image_content)
        raw_image_bytes = encoded_image.get_bytes()
        results["raw_image"] = raw_image_bytes
        print(f"✓ Raw ad visual generated ({len(raw_image_bytes)} bytes)")
        
        if fix_text:
            print("Step 4: Fixing text with OCR...")
            raw_ad_visual = RawAdVisual(raw_image_bytes)
            raw_ad_visual.save_ocr_script()
            fixed_image_bytes = raw_ad_visual.execute_ocr_correction()
            results["fixed_image"] = fixed_image_bytes
            print(f"✓ Fixed ad visual generated ({len(fixed_image_bytes)} bytes)")
        else:
            results["fixed_image"] = None
        
        return results

