# social/tasks/tiktok.py
from celery import shared_task
from django.utils import timezone
from apps.social.models import SocialAccount, SocialContent, SocialComment
from apps.social.services.tiktok import TikTokService, TikTokAPIError
import logging
import time

logger = logging.getLogger(__name__)

def parse_tiktok_timestamp(ts):
    """Convert TikTok timestamp (seconds) to datetime."""
    if not ts:
        return timezone.now()
    # TikTok timestamps are usually seconds, check if milliseconds
    if ts > 1000000000000:
        ts = ts / 1000
    return timezone.make_aware(timezone.datetime.utcfromtimestamp(ts))

@shared_task(bind=True)
def extract_all_comments_task(self, account_id):
    """
    FULL SYNC: Fetches ALL Ads and ALL Comments.
    Used for initial connection or monthly backfill.
    """
    try:
        account = SocialAccount.objects.get(id=account_id, platform_type='TT')
        if not account.is_active:
            return

        logger.info(f"Starting FULL TikTok Ads sync for {account.name}")
        
        page = 1
        has_more_ads = True
        
        while has_more_ads:
            try:
                # 1. Fetch Ads (Content)
                data = TikTokService.fetch_ads(account, page=page)
                ads = data.get('list', [])
                
                # Check pagination
                page_info = data.get('page_info', {})
                total_ads = page_info.get('total', 0)
                has_more_ads = (page * 20) < total_ads
                page += 1
                time.sleep(1)
            
                for ad_data in ads:
                    ad_id = str(ad_data['ad_id'])
                    
                    # Store Ad as SocialContent
                    content, _ = SocialContent.objects.update_or_create(
                        platform_type='TT',
                        content_id=ad_id,
                        defaults={
                            'account': account,
                            'text': ad_data.get('ad_name', ''), 
                            'created_at': parse_tiktok_timestamp(ad_data.get('create_time')),
                            'content_data': ad_data
                        }
                    )
                    
                    # 2. Fetch ALL Comments for this Ad
                    _sync_comments_for_content(account, content, ad_id, full_sync=True)
                    
            except TikTokAPIError as e:
                logger.error(f"Error syncing page {page}: {e}")
                break

    except Exception as e:
        logger.error(f"Full Sync Critical Error: {e}")

@shared_task
def poll_new_comments_task():
    """
    DELTA SYNC: Fetches comments but stops when existing comments are found.
    Run frequently (e.g., every 15 mins) via Celery Beat.
    """
    accounts = SocialAccount.objects.filter(platform_type='TT', is_active=True)
    
    for account in accounts:
        # Fetch existing Ads from our DB (we don't re-fetch Ad list every poll to save API calls)
        contents = SocialContent.objects.filter(account=account, platform_type='TT')
        
        for content in contents:
            try:
                # Sync comments, but stop early if we hit known data
                _sync_comments_for_content(account, content, content.content_id, full_sync=False)
            except TikTokAPIError as e:
                logger.error(f"Polling Error for Ad {content.content_id}: {e}")

def _sync_comments_for_content(account, content, ad_id, full_sync=True):
    """
    Helper function to sync comments for a specific Ad.
    
    Args:
        full_sync (bool): 
            True -> Fetch all pages (History).
            False -> Stop fetching pages once we find a comment we already have (Delta).
    """
    c_page = 1
    has_more_comments = True
    
    while has_more_comments:
        c_data = TikTokService.fetch_comments_for_ad(account, ad_id, page=c_page)
        comments = c_data.get('list', [])
        
        # Check pagination
        page_info = c_data.get('page_info', {})
        total_comments = page_info.get('total', 0)
        has_more_comments = (c_page * 20) < total_comments
        c_page += 1
        
        if not comments:
            break

        should_stop = False
        
        for comm in comments:
            comm_id = comm.get('comment_id')
            
            # DELTA LOGIC: If doing a poll (not full sync), check if exists
            if not full_sync:
                exists = SocialComment.objects.filter(
                    platform_type='TT', 
                    comment_id=comm_id
                ).exists()
                
                if exists:
                    # We found a comment we already have.
                    # API returns oldest -> newest usually, so we can stop.
                    should_stop = True
                    break

            # Create or Update
            comm_time = parse_tiktok_timestamp(comm.get('create_time'))
            SocialComment.objects.update_or_create(
                platform_type='TT',
                comment_id=comm_id,
                defaults={
                    'account': account,
                    'content': content,
                    'author_name': comm.get('user_name', 'Unknown'),
                    'text': comm.get('text', ''),
                    'created_at': comm_time,
                    'comment_data': comm
                }
            )
        
        if should_stop:
            break
            
        time.sleep(0.5) # Small delay to respect rate limits