#!/usr/bin/env python3
"""
Wildberries Product Data Fetcher with Playwright

Handles anti-bot protection and extracts product information
"""

import json
import re
from typing import Dict, List, Optional


def fetch_wb_product_playwright(url: str, headless: bool = True) -> Optional[Dict]:
    """
    Fetch Wildberries product data using Playwright to bypass anti-bot

    Args:
        url: WB product URL
        headless: Run browser in headless mode

    Returns:
        Product data dict with name, images, price, description
    """
    try:
        from playwright.sync_api import sync_playwright
    except ImportError:
        print("Playwright not installed. Install with: pip install playwright && playwright install chromium")
        return None

    import time

    with sync_playwright() as p:
        # Launch browser with stealth options
        browser = p.chromium.launch(
            headless=headless,
            args=[
                '--disable-blink-features=AutomationControlled',
                '--no-sandbox',
            ]
        )
        context = browser.new_context(
            viewport={"width": 1920, "height": 1080},
            user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            locale="ru-RU"
        )
        page = context.new_page()

        # Hide webdriver detection
        page.add_init_script("""
            Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
        """)

        try:
            # Navigate to product page
            print(f"Fetching: {url}")
            page.goto(url, wait_until="networkidle", timeout=30000)
            time.sleep(3)  # Additional wait for dynamic content

            # Wait for images to load (most reliable indicator)
            page.wait_for_selector('img[src*="wbbasket"]', timeout=15000)

            # Scroll to trigger lazy loading
            page.evaluate("window.scrollTo(0, 500)")
            time.sleep(1)

            # Extract product data
            product_data = page.evaluate("""() => {
                const result = {};

                // Extract name from page title (most reliable for WB)
                const titleMatch = document.title.match(/^(.+?)\\s+\\d+\\s+купить/);
                result.name = titleMatch ? titleMatch[1].trim() : '';

                // Images - collect unique product images
                const images = [];
                const seenImages = new Set();
                document.querySelectorAll('img').forEach(img => {
                    const src = img.src || img.dataset.src;
                    if (src && src.includes('/images/') && src.includes('wbbasket') && !src.includes('logo')) {
                        // Convert to big/high-res version
                        const bigSrc = src
                            .replace('/tm/', '/big/')
                            .replace('/c246x328/', '/big/')
                            .replace('/c516x688/', '/big/');
                        // Extract image number to avoid duplicates
                        const match = bigSrc.match(/\\/big\\/(\\d+)\\.webp/);
                        if (match && !seenImages.has(match[1])) {
                            seenImages.add(match[1]);
                            images.push(bigSrc);
                        }
                    }
                });
                result.images = images.sort((a, b) => {
                    const numA = parseInt(a.match(/\\/(\\d+)\\.webp/)?.[1] || 0);
                    const numB = parseInt(b.match(/\\/(\\d+)\\.webp/)?.[1] || 0);
                    return numA - numB;
                });

                // Price - try multiple selectors
                const priceSelectors = [
                    'ins.price-block__final-price',
                    '.price-block__final-price',
                    '[class*="price"] ins',
                    '.product-page__price-block ins'
                ];
                for (const sel of priceSelectors) {
                    const el = document.querySelector(sel);
                    if (el && el.textContent.match(/\\d/)) {
                        result.price = el.textContent.trim().replace(/\\s+/g, ' ');
                        break;
                    }
                }

                // Brand
                const brandEl = document.querySelector('[class*="brand"], .product-page__header-brand');
                result.brand = brandEl ? brandEl.textContent.trim() : '';

                // Description from meta or page
                const metaDesc = document.querySelector('meta[name="description"]');
                result.description = metaDesc ? metaDesc.content : '';

                return result;
            }""")

            # Extract product ID from URL
            match = re.search(r'/catalog/(\d+)/', url)
            if match:
                product_data['product_id'] = match.group(1)

            product_data['url'] = url

            # Close browser
            browser.close()

            return product_data

        except Exception as e:
            print(f"Error fetching product: {e}")
            browser.close()
            return None


def fetch_wb_images_direct(product_id: str) -> List[str]:
    """
    Generate direct image URLs for WB product
    Fallback method if Playwright fails
    """
    vol = product_id[:4]
    part = product_id[:6]

    # WB uses multiple CDN hosts
    hosts = [
        f"basket-{i:02d}.wbbasket.ru"
        for i in range(1, 21)
    ]

    # Try to determine correct host
    basket_num = (int(product_id) % 20) + 1
    host = f"basket-{basket_num:02d}.wbbasket.ru"

    # Image URLs
    images = []
    for i in range(1, 11):
        url = f"https://{host}/vol{vol}/part{part}/{product_id}/images/big/{i}.webp"
        images.append(url)

    return images


if __name__ == "__main__":
    import sys

    if len(sys.argv) < 2:
        print("Usage: python wb_fetcher.py <WB_URL>")
        sys.exit(1)

    url = sys.argv[1]
    data = fetch_wb_product_playwright(url, headless=True)

    if data:
        print(json.dumps(data, indent=2, ensure_ascii=False))
    else:
        print("Failed to fetch product data")
