"""
Instagram comment scraper using Instagram Graph API.
"""
import logging
import requests
from typing import List, Dict, Any

from .base import BaseScraper


class InstagramScraper(BaseScraper):
    """
    Scraper for Instagram comments using Instagram Graph API.
    Extracts comments from media posts.
    """
    
    BASE_URL = "https://graph.facebook.com/v19.0"
    
    def __init__(self, config: Dict[str, Any]):
        """
        Initialize Instagram scraper.
        
        Args:
            config: Dictionary with 'access_token' and optionally 'account_id'
        """
        super().__init__(config)
        self.access_token = config.get('access_token')
        if not self.access_token:
            raise ValueError(
                "Instagram access token is required. "
                "Set INSTAGRAM_ACCESS_TOKEN in your .env file."
            )
        
        self.account_id = config.get('account_id')
        if not self.account_id:
            self.logger.warning(
                "Instagram account_id not provided. "
                "Set INSTAGRAM_ACCOUNT_ID in your .env file to specify which account to scrape."
            )
        
        self.logger = logging.getLogger(self.__class__.__name__)
    
    def scrape_comments(self, account_id: str = None, **kwargs) -> List[Dict[str, Any]]:
        """
        Scrape comments from all media on an Instagram account.
        
        Args:
            account_id: Instagram account ID to scrape comments from
            
        Returns:
            List of standardized comment dictionaries
        """
        account_id = account_id or self.account_id
        if not account_id:
            raise ValueError("Instagram account ID is required")
        
        all_comments = []
        
        self.logger.info(f"Starting Instagram comment extraction for account: {account_id}")
        
        # Get all media from the account
        media_list = self._fetch_all_media(account_id)
        self.logger.info(f"Found {len(media_list)} media items to process")
        
        # Get comments for each media
        for media in media_list:
            media_id = media['id']
            media_comments = self._fetch_media_comments(media_id, media)
            all_comments.extend(media_comments)
            self.logger.info(f"Fetched {len(media_comments)} comments for media {media_id}")
        
        self.logger.info(f"Completed Instagram scraping. Total comments: {len(all_comments)}")
        return all_comments
    
    def _fetch_all_media(self, account_id: str) -> List[Dict[str, Any]]:
        """
        Fetch all media from an Instagram account.
        
        Args:
            account_id: Instagram account ID
            
        Returns:
            List of media dictionaries
        """
        url = f"{self.BASE_URL}/{account_id}/media"
        params = {
            'access_token': self.access_token,
            'fields': 'id,caption,timestamp,permalink_url,media_type'
        }
        
        all_media = []
        while url:
            try:
                response = requests.get(url, params=params)
                data = response.json()
                
                if 'error' in data:
                    self.logger.error(f"Instagram API error: {data['error']['message']}")
                    break
                
                all_media.extend(data.get('data', []))
                
                # Check for next page
                url = data.get('paging', {}).get('next')
                params = {}  # Next URL already contains params
                
            except Exception as e:
                self.logger.error(f"Error fetching media: {e}")
                break
        
        return all_media
    
    def _fetch_media_comments(self, media_id: str, media_data: Dict[str, Any]) -> List[Dict[str, Any]]:
        """
        Fetch all comments for a specific Instagram media.
        
        Args:
            media_id: Instagram media ID
            media_data: Media data dictionary
            
        Returns:
            List of standardized comment dictionaries
        """
        url = f"{self.BASE_URL}/{media_id}/comments"
        params = {
            'access_token': self.access_token,
            'fields': 'id,text,username,timestamp,like_count'
        }
        
        all_comments = []
        while url:
            try:
                response = requests.get(url, params=params)
                data = response.json()
                
                if 'error' in data:
                    self.logger.error(f"Instagram API error: {data['error']['message']}")
                    break
                
                # Process comments
                for comment_data in data.get('data', []):
                    comment = self._extract_comment(comment_data, media_id, media_data)
                    if comment:
                        all_comments.append(comment)
                
                # Check for next page
                url = data.get('paging', {}).get('next')
                params = {}  # Next URL already contains params
                
            except Exception as e:
                self.logger.error(f"Error fetching comments for media {media_id}: {e}")
                break
        
        return all_comments
    
    def _extract_comment(self, comment_data: Dict[str, Any], media_id: str, media_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        Extract and standardize an Instagram comment.
        
        Args:
            comment_data: Instagram API comment data
            media_id: Media ID
            media_data: Media data dictionary
            
        Returns:
            Standardized comment dictionary
        """
        try:
            caption = media_data.get('caption', '')
            
            comment = {
                'comment_id': comment_data['id'],
                'comments': comment_data.get('text', ''),
                'author': comment_data.get('username', ''),
                'published_at': self._parse_timestamp(comment_data.get('timestamp')),
                'like_count': comment_data.get('like_count', 0),
                'reply_count': 0,  # Instagram API doesn't provide reply count easily
                'post_id': media_id,
                'media_url': media_data.get('permalink_url'),
                'raw_data': comment_data
            }
            
            return self._standardize_comment(comment)
            
        except Exception as e:
            self.logger.error(f"Error extracting Instagram comment: {e}")
            return None
