"""Dynadot TLD price scraper.

Dynadot is a popular domain registrar known for competitive pricing
and straightforward pricing structure (less aggressive upselling).
"""
import logging
from datetime import datetime
from typing import Optional

import httpx

from app.services.tld_scraper.base import BaseTLDScraper, TLDPriceData, ScraperError

logger = logging.getLogger(__name__)


class DynadotScraper(BaseTLDScraper):
    """
    Scraper for Dynadot domain prices.
    
    Dynadot has a public TLD pricing page and relatively stable pricing.
    They're known for:
    - Competitive pricing on popular TLDs
    - Less aggressive promotional tactics than GoDaddy
    - Reasonable renewal prices
    """
    
    name = "dynadot"
    base_url = "https://www.dynadot.com"
    
    # Dynadot TLD pricing API endpoint (if available)
    PRICING_API = "https://www.dynadot.com/domain/tld-pricing.html"
    
    # Known Dynadot prices (as of Dec 2024)
    # Source: https://www.dynadot.com/domain/tld-pricing.html
    DYNADOT_PRICES = {
        # Major TLDs
        "com": {"reg": 10.99, "renew": 10.99, "transfer": 10.99},
        "net": {"reg": 12.99, "renew": 12.99, "transfer": 12.99},
        "org": {"reg": 11.99, "renew": 11.99, "transfer": 11.99},
        "info": {"reg": 3.99, "renew": 18.99, "transfer": 3.99},
        "biz": {"reg": 14.99, "renew": 14.99, "transfer": 14.99},
        
        # Premium Tech TLDs
        "io": {"reg": 34.99, "renew": 34.99, "transfer": 34.99},
        "co": {"reg": 11.99, "renew": 25.99, "transfer": 11.99},
        "ai": {"reg": 69.99, "renew": 69.99, "transfer": 69.99},
        "dev": {"reg": 13.99, "renew": 13.99, "transfer": 13.99},
        "app": {"reg": 15.99, "renew": 15.99, "transfer": 15.99},
        
        # Budget TLDs
        "xyz": {"reg": 1.99, "renew": 12.99, "transfer": 1.99},
        "tech": {"reg": 4.99, "renew": 44.99, "transfer": 4.99},
        "online": {"reg": 2.99, "renew": 34.99, "transfer": 2.99},
        "site": {"reg": 2.99, "renew": 29.99, "transfer": 2.99},
        "store": {"reg": 2.99, "renew": 49.99, "transfer": 2.99},
        "me": {"reg": 4.99, "renew": 17.99, "transfer": 4.99},
        
        # European ccTLDs
        "uk": {"reg": 8.49, "renew": 8.49, "transfer": 8.49},
        "de": {"reg": 7.99, "renew": 7.99, "transfer": 7.99},
        "eu": {"reg": 7.99, "renew": 7.99, "transfer": 7.99},
        "fr": {"reg": 9.99, "renew": 9.99, "transfer": 9.99},
        "nl": {"reg": 8.99, "renew": 8.99, "transfer": 8.99},
        "it": {"reg": 9.99, "renew": 9.99, "transfer": 9.99},
        "es": {"reg": 8.99, "renew": 8.99, "transfer": 8.99},
        "at": {"reg": 12.99, "renew": 12.99, "transfer": 12.99},
        "be": {"reg": 8.99, "renew": 8.99, "transfer": 8.99},
        "ch": {"reg": 11.99, "renew": 11.99, "transfer": 11.99},
        
        # Other popular TLDs
        "ca": {"reg": 11.99, "renew": 11.99, "transfer": 11.99},
        "us": {"reg": 8.99, "renew": 8.99, "transfer": 8.99},
        "tv": {"reg": 31.99, "renew": 31.99, "transfer": 31.99},
        "cc": {"reg": 11.99, "renew": 11.99, "transfer": 11.99},
        "in": {"reg": 9.99, "renew": 9.99, "transfer": 9.99},
        "jp": {"reg": 44.99, "renew": 44.99, "transfer": 44.99},
        
        # New gTLDs
        "club": {"reg": 1.99, "renew": 14.99, "transfer": 1.99},
        "shop": {"reg": 2.99, "renew": 32.99, "transfer": 2.99},
        "blog": {"reg": 2.99, "renew": 28.99, "transfer": 2.99},
        "cloud": {"reg": 3.99, "renew": 21.99, "transfer": 3.99},
        "live": {"reg": 2.99, "renew": 24.99, "transfer": 2.99},
        "world": {"reg": 2.99, "renew": 31.99, "transfer": 2.99},
        "global": {"reg": 69.99, "renew": 69.99, "transfer": 69.99},
        "agency": {"reg": 2.99, "renew": 22.99, "transfer": 2.99},
        "digital": {"reg": 2.99, "renew": 34.99, "transfer": 2.99},
        "media": {"reg": 2.99, "renew": 34.99, "transfer": 2.99},
        "network": {"reg": 2.99, "renew": 22.99, "transfer": 2.99},
        "software": {"reg": 2.99, "renew": 32.99, "transfer": 2.99},
        "solutions": {"reg": 2.99, "renew": 22.99, "transfer": 2.99},
        "systems": {"reg": 2.99, "renew": 22.99, "transfer": 2.99},
    }
    
    async def scrape(self) -> list[TLDPriceData]:
        """
        Scrape TLD prices from Dynadot.
        
        First attempts to fetch from their pricing page API,
        falls back to static data if unavailable.
        
        Returns:
            List of TLDPriceData objects with Dynadot pricing
        """
        # Try to scrape live data first
        try:
            live_prices = await self._scrape_live()
            if live_prices and len(live_prices) > 50:  # Got meaningful data
                return live_prices
        except Exception as e:
            logger.warning(f"Dynadot live scrape failed: {e}, using static data")
        
        # Fallback to static data
        return await self._get_static_prices()
    
    async def _scrape_live(self) -> list[TLDPriceData]:
        """Attempt to scrape live pricing data from Dynadot."""
        # Dynadot's pricing page loads via JavaScript, 
        # so we'd need Playwright for full scraping.
        # For now, return empty to use static fallback.
        return []
    
    async def _get_static_prices(self) -> list[TLDPriceData]:
        """Return static Dynadot pricing data."""
        results = []
        now = datetime.utcnow()
        
        for tld, prices in self.DYNADOT_PRICES.items():
            # Dynadot has reasonable renewal pricing for most TLDs
            is_renewal_trap = prices["renew"] > prices["reg"] * 2
            
            results.append(TLDPriceData(
                tld=tld,
                registrar="dynadot",
                registration_price=prices["reg"],
                renewal_price=prices["renew"],
                transfer_price=prices.get("transfer"),
                currency="USD",
                source="static",
                confidence=0.9,
                scraped_at=now,
                notes="Promotional intro price" if is_renewal_trap else None,
            ))
        
        logger.info(f"Loaded {len(results)} Dynadot prices (static)")
        return results
    
    async def health_check(self) -> bool:
        """Check if Dynadot is accessible."""
        try:
            async with httpx.AsyncClient(timeout=10.0) as client:
                response = await client.get(
                    self.base_url,
                    headers=self.get_headers(),
                    follow_redirects=True,
                )
                return response.status_code == 200
        except Exception as e:
            logger.debug(f"Dynadot health check failed: {e}")
            return False

