# social/services/tiktok.py
import requests
import datetime
import time
import logging
from django.conf import settings
from django.utils import timezone
from apps.social.utils.tiktok import TikTokConstants
from apps.social.models import SocialAccount

logger = logging.getLogger(__name__)

class TikTokAPIError(Exception):
    pass

class TikTokService:

    @staticmethod
    def get_auth_url():
        state = "random_secure_string" # Ideally generate dynamically
        return (
            f"{TikTokConstants.ENDPOINTS['AUTH']}"
            f"?app_id={settings.TIKTOK_CLIENT_KEY}"
            f"&state={state}"
            f"&scope={TikTokConstants.SCOPES}"
            f"&redirect_uri={settings.TIKTOK_REDIRECT_URI}"
        )

    @staticmethod
    def exchange_code_for_token(code):
        url = f"{TikTokConstants.BASE_URL}{TikTokConstants.ENDPOINTS['TOKEN']}"
        payload = {
            "app_id": settings.TIKTOK_CLIENT_KEY,
            "secret": settings.TIKTOK_CLIENT_SECRET,
            "auth_code": code,
        }
        resp = requests.post(url, json=payload)
        data = resp.json()
        
        if data.get('code') != 0:
            logger.error(f"TikTok Token Error: {data}")
            raise TikTokAPIError(data.get('message', 'Token exchange failed'))
        
        return data.get('data', {})

    @staticmethod
    def refresh_tokens(account):
        url = f"{TikTokConstants.BASE_URL}{TikTokConstants.ENDPOINTS['TOKEN']}"
        payload = {
            "app_id": settings.TIKTOK_CLIENT_KEY,
            "secret": settings.TIKTOK_CLIENT_SECRET,
            "refresh_token": account.refresh_token,
        }
        resp = requests.post(url, json=payload)
        data = resp.json()
        
        if data.get('code') != 0:
            account.is_active = False
            account.save()
            raise TikTokAPIError("Refresh Failed")
        
        token_data = data.get('data', {})
        account.access_token = token_data['access_token']
        account.refresh_token = token_data['refresh_token']
        account.expires_at = timezone.now() + datetime.timedelta(seconds=token_data.get('expires_in', 86400))
        account.save()
        return account

    @staticmethod
    def get_valid_token(account):
        if account.expires_at <= timezone.now() + datetime.timedelta(minutes=5):
            account = TikTokService.refresh_tokens(account)
        return account.access_token

    @staticmethod
    def make_api_request(endpoint, account, payload=None, method="POST"):
        token = TikTokService.get_valid_token(account)
        headers = {
            "Access-Token": token, # Business API specific header
            "Content-Type": "application/json"
        }
        url = f"{TikTokConstants.BASE_URL}{endpoint}"
        
        if payload is None:
            payload = {}
            
        # CRITICAL: Business API requires advertiser_id in the body
        if not account.platform_id:
            raise TikTokAPIError("Advertiser ID is missing from account configuration.")
        
        payload['advertiser_id'] = account.platform_id

        try:
            # Business API primarily uses POST for data retrieval
            if method == "POST":
                response = requests.post(url, headers=headers, json=payload)
            else:
                response = requests.get(url, headers=headers, params=payload)
            
            data = response.json()
            
            if data.get('code') != 0:
                raise TikTokAPIError(f"API Error {data.get('code')}: {data.get('message')}")
                
            return data.get('data', {})
            
        except Exception as e:
            raise TikTokAPIError(str(e))

    @staticmethod
    def fetch_ads(account, page=1, page_size=20):
        """Fetch Ads to act as 'Content' containers for comments."""
        payload = {
            "page": page,
            "page_size": page_size,
            # Filtering could be added here, e.g., filtering by active status
        }
        return TikTokService.make_api_request(TikTokConstants.ENDPOINTS['AD_LIST'], account, payload)

    @staticmethod
    def fetch_comments_for_ad(account, ad_id, page=1, page_size=20):
        """Fetch comments for a specific Advertisement."""
        payload = {
            # 'item_id' in Business API context is the Ad ID
            "item_id": ad_id, 
            "page": page,
            "page_size": page_size,
        }
        return TikTokService.make_api_request(TikTokConstants.ENDPOINTS['COMMENT_LIST'], account, payload)

    @staticmethod
    def reply_to_comment(account, ad_id, comment_id, text):
        """Reply to a comment on an Advertisement."""
        payload = {
            "item_id": ad_id,      # Ad ID required
            "comment_id": comment_id,
            "text": text
        }
        return TikTokService.make_api_request(TikTokConstants.ENDPOINTS['COMMENT_REPLY'], account, payload)