# xcom/tasks.py

from celery import shared_task
from django.utils import timezone
from django.utils.dateparse import parse_datetime
from apps.social.models import SocialAccount, SocialContent, SocialComment
from apps.social.services.x import XService, XAPIError, XRateLimitError
import logging

logger = logging.getLogger(__name__)

def parse_x_timestamp(ts):
    if not ts: return timezone.now()
    try:
        dt = parse_datetime(ts)
        return dt if dt else timezone.now()
    except:
        return timezone.now()

@shared_task
def sync_all_accounts_periodic():
    logger.info("Starting Periodic Polling for X (Twitter)...")
    accounts = SocialAccount.objects.filter(platform_type='X', is_active=True)
    
    for account in accounts:
        try:
            poll_new_replies_task.delay(account.id)
        except Exception as e:
            logger.error(f"Failed to trigger sync for account {account.id}: {e}")

@shared_task(bind=True, max_retries=6) # Allow retries for rate limits
def poll_new_replies_task(self, account_id):
    """
    DELTA SYNC TASK with intelligent Rate Limit handling.
    """
    try:
        account = SocialAccount.objects.get(id=account_id, platform_type='X')
        tweets = SocialContent.objects.filter(platform_type='X', account=account)
        
        for tweet in tweets:
            if not tweet.last_comment_sync_at:
                continue # Skip unsynced tweets

            try:
                replies_data = XService.fetch_tweet_replies(
                    account, 
                    tweet.content_id,
                    since_datetime=tweet.last_comment_sync_at, 
                    owner_id=account.platform_id
                )
            except XRateLimitError as e:
                # CRITICAL: Don't block. Retry later using ETA (Estimated Time of Arrival)
                # Add a buffer of 60 seconds to ensure limit is reset
                retry_time = timezone.make_aware(datetime.datetime.fromtimestamp(e.reset_at))
                wait_seconds = (retry_time - timezone.now()).total_seconds() + 60
                
                logger.warning(f"Rate limit hit. Retrying in {wait_seconds} seconds.")
                raise self.retry(exc=XAPIError("Rate limit triggered"), countdown=wait_seconds)

            if not replies_data:
                continue

            newest_timestamp_found = tweet.last_comment_sync_at

            for r_data in replies_data:
                # r_data['author'] is now populated by _attach_expansions
                author = r_data.get('author')
                
                if not author:
                    # Fallback if expansion failed (shouldn't happen)
                    continue

                r_time = parse_x_timestamp(r_data['created_at'])
                if r_time <= tweet.last_comment_sync_at:
                    continue

                SocialComment.objects.update_or_create(
                    platform_type='X',
                    comment_id=r_data['id'],
                    defaults={
                        'account': account,
                        'content': tweet,
                        'text': r_data.get('text', ''),
                        'author_id': author.get('id'),
                        'author_name': author.get('username', 'Unknown'), # Now correctly fetched
                        'created_at': r_time,
                        'comment_data': r_data
                    }
                )
                
                if r_time > newest_timestamp_found:
                    newest_timestamp_found = r_time

            if newest_timestamp_found > tweet.last_comment_sync_at:
                tweet.last_comment_sync_at = newest_timestamp_found
                tweet.save()
        
        account.last_synced_at = timezone.now()
        account.save()
        
    except SocialAccount.DoesNotExist:
        logger.error(f"Account {account_id} not found")
    except XRateLimitError:
        # Raise it again if we haven't retried enough times
        raise 
    except Exception as e:
        logger.error(f"Polling Error for account {account_id}: {e}")


@shared_task(bind=True)
def extract_all_replies_task(self, account_id):
    """
    MANUAL FULL SYNC (Backfill)
    """
    try:
        account = SocialAccount.objects.get(id=account_id, platform_type='X')
        
        tweets_data = XService.get_user_tweets(account)
        
        if not tweets_data:
            logger.info(f"No tweets found for account {account.name}")
            return

        for t_data in tweets_data:
            tweet_id = t_data['id']
            
            tweet, created = SocialContent.objects.get_or_create(
                platform_type='X',
                content_id=tweet_id,
                defaults={
                    'account': account,
                    'text': t_data.get('text', ''),
                    'created_at': parse_x_timestamp(t_data['created_at']),
                    'content_data': t_data
                }
            )
            
            # Rate limit handling for fetch inside backfill
            try:
                replies_data = XService.fetch_tweet_replies(
                    account, 
                    tweet_id, 
                    since_datetime=None, 
                    owner_id=account.platform_id
                )
            except XRateLimitError as e:
                 # Retry backfill later
                retry_time = timezone.make_aware(datetime.datetime.fromtimestamp(e.reset_at))
                wait_seconds = (retry_time - timezone.now()).total_seconds() + 60
                raise self.retry(exc=XAPIError("Rate limit triggered"), countdown=wait_seconds)

            if not replies_data:
                continue

            for r_data in replies_data:
                author = r_data.get('author')
                if not author: continue
                
                SocialComment.objects.update_or_create(
                    platform_type='X',
                    comment_id=r_data['id'],
                    defaults={
                        'account': account,
                        'content': tweet,
                        'text': r_data.get('text', ''),
                        'author_id': author.get('id'),
                        'author_name': author.get('username', 'Unknown'),
                        'created_at': parse_x_timestamp(r_data['created_at']),
                        'comment_data': r_data
                    }
                )
            
            if created:
                tweet.last_comment_sync_at = tweet.created_at
                tweet.save()

        account.last_synced_at = timezone.now()
        account.save()

    except SocialAccount.DoesNotExist:
        logger.error(f"Account {account_id} not found")
    except XRateLimitError:
        raise
    except Exception as e:
        logger.error(f"Backfill Error for account {account_id}: {e}")