import httpx
import re
import json
import logging
import random
import time
from angel_claw.skills.manager import skill
from typing import List, Dict, Optional
import urllib.parse

logger = logging.getLogger("angel-claw-image-search")

def bing_image_search(query: str, count: int = 3) -> List[str]:
    '''
    Internal helper to scrape Bing Image results.
    '''
    urls = []
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
    }
    # Bing image search URL
    search_url = f"https://www.bing.com/images/search?q={urllib.parse.quote(query)}"
    
    try:
        with httpx.Client(headers=headers, follow_redirects=True, timeout=15) as client:
            response = client.get(search_url)
            response.raise_for_status()
            html = response.text
            
            # Extract image metadata from 'm' attributes in Bing HTML
            matches = re.findall(r'm="({.*?})"', html)
            for m in matches:
                try:
                    # Bing uses HTML entities for quotes inside the attribute
                    clean_json = m.replace('&quot;', '"')
                    data = json.loads(clean_json)
                    if 'murl' in data:
                        # Encode the URL to handle spaces and special characters
                        raw_url = data['murl']
                        # We use safe characters for URL parsing
                        encoded_url = urllib.parse.quote(raw_url, safe=':/?&=#%')
                        urls.append(encoded_url)
                        if len(urls) >= count:
                            break
                except Exception:
                    continue
                    
        return urls
    except Exception as e:
        logger.error(f"Bing search request failed: {e}")
        return []

@skill
def search_images(query: str, count: int = 3) -> str:
    '''
    MANDATORY TOOL for showing images. 
    Use this WHENEVER the user asks for pictures, photos, or images. 
    You MUST call this tool to display visual content. 
    NEVER use Markdown syntax like ![alt](url) for images; ALWAYS use this tool instead.
    The images will be correctly rendered as photos for the user in Telegram/WhatsApp.

    Args:
        query: Descriptive search term for the images.
        count: Number of images (default 3, max 10).
    '''
    try:
        # Normalize input
        safe_count = int(count or 3)
        safe_count = max(1, min(safe_count, 10))
        
        logger.info(f"Searching images for: {query} (count={safe_count})")
        
        # Add a tiny delay to prevent rapid-fire blocking
        time.sleep(random.uniform(0.5, 1.0))
        
        image_urls = bing_image_search(query, safe_count)
        
        if not image_urls:
            logger.warning(f"No results found for query: {query}")
            return f"I couldn't find any images for '{query}' right now. Please try a different search term."

        # Format for the Telegram bridge to detect and send as photos
        formatted_results = [f"[IMAGE: {url}]" for url in image_urls]
        
        return f"I found some images for '{query}':\n" + "\n".join(formatted_results)

    except Exception as e:
        logger.error(f"Error in search_images skill: {e}")
        return f"Sorry, there was a problem searching for images: {e}"
