"""Data extraction utilities."""

import json
from typing import Any

from playwright.async_api import Page


async def extract_table(page: Page, selector: str = "table") -> list[dict[str, str]]:
    """
    Extract data from an HTML table.
    
    Args:
        page: Playwright page object
        selector: CSS selector for the table
        
    Returns:
        List of dictionaries representing table rows
    """
    table_data = await page.evaluate("""
        (selector) => {
            const table = document.querySelector(selector);
            if (!table) return [];
            
            const headers = Array.from(table.querySelectorAll('th')).map(th => th.innerText.trim());
            const rows = Array.from(table.querySelectorAll('tr')).slice(1); // Skip header row
            
            return rows.map(row => {
                const cells = Array.from(row.querySelectorAll('td'));
                const rowData = {};
                cells.forEach((cell, index) => {
                    const key = headers[index] || `col_${index}`;
                    rowData[key] = cell.innerText.trim();
                });
                return rowData;
            });
        }
    """, selector)
    
    return table_data


async def extract_list(page: Page, selector: str) -> list[str]:
    """
    Extract text from a list of elements.
    
    Args:
        page: Playwright page object
        selector: CSS selector for list items
        
    Returns:
        List of text content
    """
    items = await page.query_selector_all(selector)
    texts = []
    for item in items:
        text = await item.inner_text()
        if text:
            texts.append(text.strip())
    return texts


async def extract_links(page: Page, selector: str = "a") -> list[dict[str, str]]:
    """
    Extract links from the page.
    
    Args:
        page: Playwright page object
        selector: CSS selector for links
        
    Returns:
        List of dictionaries with text and href
    """
    links = await page.query_selector_all(selector)
    results = []
    for link in links:
        text = await link.inner_text()
        href = await link.get_attribute("href")
        if text and href:
            results.append({
                "text": text.strip()[:100],  # Limit text length
                "href": href
            })
    return results


async def smart_extract(page: Page, instruction: str) -> Any:
    """
    Smart extraction based on instruction.
    
    Args:
        page: Playwright page object
        instruction: What to extract (e.g., "all links", "table data", "prices")
        
    Returns:
        Extracted data in appropriate format
    """
    instruction_lower = instruction.lower()
    
    # Detect extraction type from instruction
    if "table" in instruction_lower or "表格" in instruction_lower:
        return await extract_table(page)
    
    if "link" in instruction_lower or "链接" in instruction_lower:
        return await extract_links(page)
    
    if "list" in instruction_lower or "列表" in instruction_lower:
        # Try common list selectors
        selectors = ["ul li", "ol li", ".list-item", "[class*='list'] li"]
        for selector in selectors:
            items = await extract_list(page, selector)
            if items:
                return items
        return []
    
    if "price" in instruction_lower or "价格" in instruction_lower:
        # Look for price patterns
        prices = await page.evaluate(r"""
            () => {
                const elements = document.querySelectorAll('*');
                const prices = [];
                const priceRegex = /[\u00a5\u0024\u20ac\u00a3]\s*[\d,]+(\.\d{2})?|[\d,]+(\.\d{2})?\s*[\u00a5\u0024\u20ac\u00a3]/;
                elements.forEach(el => {
                    const text = el.innerText;
                    if (text && priceRegex.test(text)) {
                        prices.push(text.trim());
                    }
                });
                return [...new Set(prices)].slice(0, 20);
            }
        """)
        return prices
    
    # Default: extract text from common content areas
    selectors = ["main", "article", "[role='main']", ".content", "#content", "body"]
    for selector in selectors:
        element = await page.query_selector(selector)
        if element:
            text = await element.inner_text()
            if text:
                return text[:5000]  # Limit length
    
    return ""
