"""Twitter site preset with render support."""
import time
import random
import re
import logging

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


class Twitter:
    RATE_LIMIT = 5
    _last_request = 0

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

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

    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 _mobile_headers(self):
        from ..fingerprint import chrome_fingerprint
        return chrome_fingerprint("US")

    def _validate_twitter_profile(self, html: str) -> bool:
        """Check if we got a real Twitter profile (not login wall/error)."""
        if not html:
            return False
        
        # Check for login wall/block indicators
        block_indicators = [
            'login-container',
            'signup-container', 
            'LoginForm',
            'data-testid="loginButton"',
            'Sign up for Twitter',
            'Log in to Twitter',
            '"guestNotAllowed"',
            'age-gate',
            'Something went wrong'
        ]
        
        if any(indicator in html for indicator in block_indicators):
            return False
        
        # Check for actual profile content
        profile_indicators = [
            'data-testid="UserName"',
            'data-testid="UserDescription"',
            'data-testid="Following"',
            'data-testid="Followers"',
            'ProfileHeaderCard',
            'data-testid="tweet"',
            'class="css-1dbjc4n r-1awozwy"',  # Profile layout
            'aria-label="Home timeline"'
        ]
        
        return any(indicator in html for indicator in profile_indicators)

    def _extract_twitter_profile(self, html: str) -> dict:
        """Extract profile data from Twitter HTML and meta tags."""
        data = {}
        
        # Extract from og:description meta tag (often has bio text)
        og_desc_match = re.search(r'<meta property="og:description" content="([^"]*)"', html)
        if og_desc_match:
            data['bio'] = og_desc_match.group(1).strip()
        
        # Extract from og:title (name)
        og_title_match = re.search(r'<meta property="og:title" content="([^"]*)"', html)
        if og_title_match:
            title = og_title_match.group(1)
            # Title format is usually "Name (@username) / Twitter"
            name_match = re.search(r'^([^(]+)', title)
            if name_match:
                data['name'] = name_match.group(1).strip()
        
        # Extract display name from testid
        name_match = re.search(r'data-testid="UserName"[^>]*>([^<]+)', html)
        if name_match:
            data['name'] = name_match.group(1).strip()
        
        # Extract bio/description from testid
        bio_match = re.search(r'data-testid="UserDescription"[^>]*><span[^>]*>(.*?)</span>', html, re.DOTALL)
        if bio_match:
            bio_text = self._extract_text(bio_match.group(1))
            if bio_text and not data.get('bio'):
                data['bio'] = bio_text
        
        # Extract follower count
        followers_match = re.search(r'(\d+(?:,\d+)*(?:\.\d+)?[KMB]?)\s*Followers', html, re.IGNORECASE)
        if followers_match:
            data['followers'] = followers_match.group(1)
        
        # Extract following count
        following_match = re.search(r'(\d+(?:,\d+)*(?:\.\d+)?[KMB]?)\s*Following', html, re.IGNORECASE)
        if following_match:
            data['following'] = following_match.group(1)
        
        # Extract tweet count (from profile stats)
        tweets_match = re.search(r'(\d+(?:,\d+)*(?:\.\d+)?[KMB]?)\s*Tweets', html, re.IGNORECASE)
        if tweets_match:
            data['tweets_count'] = tweets_match.group(1)
        
        # Extract verification status
        if 'verified-profile' in html or 'data-testid="verificationBadge"' in html:
            data['verified'] = True
        
        # Extract location from meta tags
        location_match = re.search(r'"location":\s*"([^"]*)"', html)
        if location_match and location_match.group(1):
            data['location'] = location_match.group(1)
        
        # Extract website from meta tags
        website_match = re.search(r'"url":\s*"([^"]*)"', html)
        if website_match and website_match.group(1):
            data['website'] = website_match.group(1)
        
        return data

    def profile(self, username, extract=True):
        """
        Fetch Twitter profile page with render support.
        Twitter requires rendering for full content.
        """
        self._rate_limit()
        url = f"https://twitter.com/{username}"
        
        # Twitter needs render for content
        if hasattr(self.client, 'render_fetch'):
            try:
                html = self.client.render_fetch(
                    url, 
                    country="US", 
                    wait_for='[data-testid="UserName"]',
                    wait_time=5
                )
                
                if self._validate_twitter_profile(html):
                    result = {
                        "username": username,
                        "url": url,
                        "status": 200,
                        "html": html,
                        "size_kb": len(html) // 1024,
                        "source": "render"
                    }
                    
                    if extract:
                        result.update(self._extract_twitter_profile(html))
                    
                    return result
                else:
                    logger.warning("Twitter render returned login wall/blocked content")
                    
            except Exception as e:
                logger.error(f"Twitter render failed: {e}")
        
        # Fallback to HTTP (limited content)
        resp = self.client.fetch(url, country="US", headers=self._mobile_headers())
        
        result = {
            "username": username,
            "url": url,
            "status": resp.status_code,
            "html": resp.text,
            "size_kb": len(resp.text) // 1024,
            "source": "http"
        }
        
        if extract and resp.status_code == 200:
            # Try to extract what we can from meta tags
            result.update(self._extract_twitter_profile(resp.text))
        
        return result

    def tweet(self, tweet_id):
        """Fetch a specific tweet with render support."""
        self._rate_limit()
        url = f"https://twitter.com/i/status/{tweet_id}"
        
        # Try render first
        if hasattr(self.client, 'render_fetch'):
            try:
                html = self.client.render_fetch(url, country="US", wait_time=3)
                return {
                    "tweet_id": tweet_id,
                    "url": url,
                    "status": 200,
                    "html": html,
                    "source": "render"
                }
            except Exception as e:
                logger.error(f"Tweet render failed: {e}")
        
        # Fallback to HTTP
        resp = self.client.fetch(url, country="US", headers=self._mobile_headers())
        return {
            "tweet_id": tweet_id,
            "url": url,
            "status": resp.status_code,
            "html": resp.text,
            "source": "http"
        }

    def search(self, query, country="US"):
        """Search Twitter with render support."""
        self._rate_limit()
        import urllib.parse
        encoded_query = urllib.parse.quote_plus(query)
        url = f"https://twitter.com/search?q={encoded_query}&src=typed_query"
        
        # Search needs render for content
        if hasattr(self.client, 'render_fetch'):
            try:
                html = self.client.render_fetch(url, country=country, wait_time=5)
                return {
                    "query": query,
                    "url": url,
                    "status": 200,
                    "html": html,
                    "source": "render"
                }
            except Exception as e:
                logger.error(f"Twitter search render failed: {e}")
        
        # Fallback to HTTP
        resp = self.client.fetch(url, country=country, headers=self._mobile_headers())
        return {
            "query": query,
            "url": url,
            "status": resp.status_code,
            "html": resp.text,
            "source": "http"
        }
