__all__ = ["Internet_Search_Stream_LMMH","Check_Image_Size_Sync_LMMH"]



import aiohttp
import asyncio
from googlesearch import search
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from PIL import Image
from io import BytesIO

from ddgs import DDGS


    
    
def Check_Image_Size_Sync_LMMH(img_bytes):
    try:
        image = Image.open(BytesIO(img_bytes))
        return image.size
    except:
        return 0, 0

async def fetch(session, url):
    try:
        async with session.get(url, timeout=10) as response:
            if response.status == 200:
                return url, await response.text()
    except:
        return url, None
    return url, None

async def Internet_Search_Stream_LMMH(query, num_paragraphs_results=20, min_length=300, num_results=10):
    from .misc_utils import Check_Internet_Connection_LMMH
    if not Check_Internet_Connection_LMMH():
        yield query
        return

    headers = {"User-Agent": "Mozilla/5.0"}
    seen_images = set()
    seen_texts = set()
    collected = 0
    DataSearch = ""

    with DDGS() as ddgs:
        print("-------------------------")
        results = list(ddgs.text(query, max_results=num_results))  # Ensure list is materialized
        for result in results:
            print("++++++++++++++++++++")
            print(result['href'])  # or print(result) to see all available fields
            
    async with aiohttp.ClientSession(headers=headers) as session:
        tasks = [fetch(session, result['href']) for result in results]
        for future in asyncio.as_completed(tasks):
            url, html = await future

            if collected >= num_paragraphs_results:
                break
            if not html:
                continue

            soup = BeautifulSoup(html, 'html.parser')

            for section in soup.find_all(['article', 'main', 'div']):
                for p in section.find_all('p'):
                    text = p.get_text(strip=True)
                    if len(text) < min_length or text in seen_texts:
                        continue

                    seen_texts.add(text)
                    progress = (collected / num_paragraphs_results) * 100
                    yield f"Reading: {url} ({progress:.1f}%)"

                    DataSearch += "\n\n" + text

                    # Try finding related images
                    parent = p.find_parent(['article', 'main', 'div'])
                    if parent:
                        img_count = 0
                        for img in parent.find_all('img'):
                            if img_count >= 4:
                                break
                            src = img.get('src')
                            if not src:
                                continue
                            full_img_url = urljoin(url, src)
                            if full_img_url in seen_images:
                                continue

                            width = img.get('width')
                            height = img.get('height')
                            try:
                                width = int(width) if width else 0
                                height = int(height) if height else 0
                            except:
                                width, height = 0, 0

                            if width < 100 or height < 100:
                                try:
                                    async with session.get(full_img_url, timeout=5) as img_resp:
                                        if "image" in img_resp.headers.get("Content-Type", ""):
                                            img_bytes = await img_resp.read()
                                            loop = asyncio.get_event_loop()
                                            width, height = await loop.run_in_executor(None, Check_Image_Size_Sync_LMMH, img_bytes)
                                except:
                                    continue

                            if width >= 200 and height >= 200:
                                seen_images.add(full_img_url)
                                DataSearch += f"\n![image]({full_img_url})"
                                img_count += 1

                    collected += 1
                    if collected >= num_paragraphs_results:
                        break

                if collected >= num_paragraphs_results:
                    break

    if not DataSearch.strip():
        yield f"'{query}'"
    else:
        yield f"The user asked about '{query}'. The following data was retrieved from an internet search:\n\n{DataSearch}\n\nIf the data contains image links in the format ![image]({{full_img_url}}), include **all** of them. Do not add any image tags or links unless actual images are present in the data."

