"""Stock quote preset using Yahoo Finance (Nasdaq blocks via Akamai)."""
import time
import random
import re
import json
import logging

logger = logging.getLogger("iploop.sites.nasdaq")


class Nasdaq:
    RATE_LIMIT = 5
    _last_request = 0

    def __init__(self, client):
        self.client = client

    def _rate_limit(self):
        elapsed = time.time() - Nasdaq._last_request
        if elapsed < self.RATE_LIMIT:
            time.sleep(self.RATE_LIMIT - elapsed + random.uniform(0, 2))
        Nasdaq._last_request = time.time()

    def _extract_yahoo_quote(self, html: str, symbol: str) -> dict:
        """Extract stock data from Yahoo Finance HTML."""
        data = {"symbol": symbol}
        
        # Extract from JSON-LD script tags
        json_ld_match = re.search(r'<script type="application/ld\+json"[^>]*>({.+?})</script>', html, re.DOTALL)
        if json_ld_match:
            try:
                json_data = json.loads(json_ld_match.group(1))
                price_data = json_data.get('mainEntity', {}).get('price', {})
                
                if price_data:
                    data.update({
                        'price': price_data.get('price'),
                        'currency': price_data.get('priceCurrency'),
                        'change': price_data.get('priceChange'),
                        'change_percent': price_data.get('priceChangePercent')
                    })
            except (json.JSONDecodeError, KeyError):
                pass
        
        # Extract from meta tags
        price_match = re.search(r'data-symbol="[^"]*"\s+data-field="regularMarketPrice"\s+data-trend="[^"]*"\s+data-pricehint="\d+">([^<]+)', html)
        if price_match:
            data['price'] = price_match.group(1).strip()
        
        # Extract change
        change_match = re.search(r'data-field="regularMarketChange"[^>]*>([^<]+)', html)
        if change_match:
            data['change'] = change_match.group(1).strip()
        
        # Extract change percentage
        change_percent_match = re.search(r'data-field="regularMarketChangePercent"[^>]*>([^<]+)', html)
        if change_percent_match:
            data['change_percent'] = change_percent_match.group(1).strip()
        
        # Extract volume
        volume_match = re.search(r'data-field="regularMarketVolume"[^>]*>([^<]+)', html)
        if volume_match:
            data['volume'] = volume_match.group(1).strip()
        
        # Extract market cap
        market_cap_match = re.search(r'Market Cap[^>]*>([^<]+)', html, re.IGNORECASE)
        if market_cap_match:
            data['market_cap'] = market_cap_match.group(1).strip()
        
        # Extract 52-week high/low
        high_52w_match = re.search(r'52[- ]?Week High[^>]*>([^<]+)', html, re.IGNORECASE)
        if high_52w_match:
            data['52_week_high'] = high_52w_match.group(1).strip()
        
        low_52w_match = re.search(r'52[- ]?Week Low[^>]*>([^<]+)', html, re.IGNORECASE)
        if low_52w_match:
            data['52_week_low'] = low_52w_match.group(1).strip()
        
        # Extract P/E ratio
        pe_match = re.search(r'P/E Ratio[^>]*>([^<]+)', html, re.IGNORECASE)
        if pe_match:
            data['pe_ratio'] = pe_match.group(1).strip()
        
        return data

    def _extract_text(self, html: str) -> str:
        """Strip HTML tags and return clean text."""
        # Remove HTML tags
        text = re.sub(r'<[^>]+>', '', html)
        # Clean up whitespace
        text = re.sub(r'\s+', ' ', text).strip()
        return text

    def _try_yahoo_api(self, symbol: str, country: str = "US") -> dict:
        """Try Yahoo Finance API endpoint - JSON API, no HTML parsing needed."""
        # Yahoo Finance query API - returns JSON directly
        url = f"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}?interval=1d"
        
        try:
            resp = self.client.fetch(url, timeout=10, headers={
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            })
            
            if resp.status_code == 200:
                # Parse JSON response directly - no HTML parsing needed
                data = json.loads(resp.text)
                chart_data = data.get('chart', {}).get('result', [])
                
                if chart_data:
                    quote_data = chart_data[0].get('meta', {})
                    current_price = quote_data.get('regularMarketPrice')
                    previous_close = quote_data.get('previousClose', 0)
                    
                    # Calculate change and change percent
                    change = current_price - previous_close if current_price and previous_close else None
                    change_percent = (change / previous_close * 100) if change and previous_close else None
                    
                    return {
                        'symbol': symbol,
                        'status': 200,
                        'source': 'yahoo_api',
                        'data': {
                            'price': current_price,
                            'change': change,
                            'change_percent': change_percent,
                            'volume': quote_data.get('regularMarketVolume'),
                            'market_cap': quote_data.get('marketCap'),
                            'currency': quote_data.get('currency'),
                            'exchange': quote_data.get('exchangeName'),
                            'previous_close': previous_close,
                            '52_week_high': quote_data.get('fiftyTwoWeekHigh'),
                            '52_week_low': quote_data.get('fiftyTwoWeekLow')
                        }
                    }
        except Exception as e:
            logger.debug(f"Yahoo Finance API failed: {e}")
        
        return None

    def quote(self, symbol, country="US", extract=True):
        """
        Fetch stock quote using Yahoo Finance (Nasdaq blocks via Akamai).
        Try API first, fallback to page scraping.
        """
        self._rate_limit()
        
        # First try Yahoo Finance API
        api_result = self._try_yahoo_api(symbol, country)
        if api_result:
            return api_result
        
        # Fallback to Yahoo Finance web page
        url = f"https://finance.yahoo.com/quote/{symbol}"
        
        # Try render for dynamic content
        if hasattr(self.client, 'render_fetch'):
            try:
                html = self.client.render_fetch(
                    url,
                    country=country,
                    wait_for='[data-field="regularMarketPrice"]',
                    wait_time=3
                )
                
                result = {
                    "symbol": symbol,
                    "url": url,
                    "status": 200,
                    "html": html,
                    "size_kb": len(html) // 1024,
                    "source": "yahoo_render"
                }
                
                if extract:
                    result["data"] = self._extract_yahoo_quote(html, symbol)
                
                return result
                
            except Exception as e:
                logger.error(f"Yahoo Finance render failed: {e}")
        
        # Final fallback to HTTP
        from ..fingerprint import chrome_fingerprint
        resp = self.client.fetch(url, country=country, headers=chrome_fingerprint("US"))
        
        result = {
            "symbol": symbol,
            "url": url,
            "status": resp.status_code,
            "html": resp.text,
            "size_kb": len(resp.text) // 1024,
            "source": "yahoo_http"
        }
        
        if extract and resp.status_code == 200:
            result["data"] = self._extract_yahoo_quote(resp.text, symbol)
        
        return result

    def news(self, symbol, country="US"):
        """Fetch stock news from Yahoo Finance."""
        self._rate_limit()
        url = f"https://finance.yahoo.com/quote/{symbol}/news"
        
        resp = self.client.fetch(url, country=country)
        return {
            "symbol": symbol,
            "url": url,
            "status": resp.status_code,
            "html": resp.text,
            "source": "yahoo_http"
        }

    def market_summary(self, country="US"):
        """Fetch market summary from Yahoo Finance."""
        self._rate_limit()
        url = "https://finance.yahoo.com/"
        
        resp = self.client.fetch(url, country=country)
        return {
            "url": url,
            "status": resp.status_code,
            "html": resp.text,
            "source": "yahoo_http"
        }
