import requests, os
from urllib.parse import quote

BASE = 'https://api.linkedin.com'

def _headers():
    return {
        'Authorization': 'Bearer {}'.format(os.getenv('LINKEDIN_ACCESS_TOKEN')),
        'Content-Type': 'application/json',
        'LinkedIn-Version': '202312',
    }

def _member_id():
    return os.getenv('LINKEDIN_MEMBER_ID')

def get_changelog_events(start_time_ms=None, count=50):
    """
    Recupere les evenements du changelog DMA (posts, commentaires, reactions).
    start_time_ms : timestamp epoch en millisecondes pour ne recuperer
                    que les nouveaux evenements depuis la derniere verification.
    Retourne la liste des elements.
    """
    url = '{}/rest/memberChangeLogs?q=memberAndApplication&count={}'.format(BASE, count)
    if start_time_ms:
        url += '&startTime={}'.format(int(start_time_ms))
    r = requests.get(url, headers=_headers())
    r.raise_for_status()
    return r.json().get('elements', [])

def get_comment_events(start_time_ms=None):
    """
    Filtre les evenements du changelog pour ne garder que les commentaires
    recus sur les posts de Jimmy (CREATE sur ressource de type comment,
    dont l'acteur n'est pas Jimmy lui-meme).
    """
    my_id = _member_id() or ''
    my_short_id = my_id.replace('urn:li:person:', '')
    events = get_changelog_events(start_time_ms=start_time_ms)
    comments = []
    for event in events:
        method = event.get('method', '')
        resource = event.get('resourceName', '').lower()
        actor = event.get('actor', '')

        if method != 'CREATE':
            continue
        if 'comment' not in resource:
            continue
        # Ignorer les propres commentaires de Jimmy
        if my_short_id and my_short_id in actor:
            continue

        comments.append(event)
    return comments

def extract_comment_text(event):
    """Extrait le texte du commentaire depuis un evenement changelog."""
    activity = event.get('activity', {})
    # Le texte peut etre dans activity.message.text ou activity.text
    msg = activity.get('message', {})
    if isinstance(msg, dict):
        return msg.get('text', '')
    text = activity.get('text', '')
    if isinstance(text, dict):
        return text.get('text', '')
    return str(text) if text else ''

def extract_post_urn(event):
    """Extrait l'URN du post parent depuis un evenement commentaire."""
    activity = event.get('activity', {})
    # Le post parent peut etre dans rootPost, parentPost, ou container
    for key in ('rootPost', 'parentPost', 'container', 'parentUrn', 'rootShare'):
        val = activity.get(key)
        if val:
            if isinstance(val, dict):
                return val.get('urn') or val.get('id') or ''
            return str(val)
    # Fallback: resourceUri peut contenir l'info
    return event.get('resourceUri', '')

def extract_actor_info(event):
    """
    Extrait les infos du commentateur depuis un evenement changelog.
    Retourne un dict : profile_url, first_name, last_name, linkedin_id.
    """
    actor    = event.get('actor', '')       # ex: 'urn:li:person:ABC123'
    activity = event.get('activity', {})

    # Extraire l'ID depuis l'URN LinkedIn
    linkedin_id = ''
    if 'urn:li:person:' in actor:
        linkedin_id = actor.replace('urn:li:person:', '').strip()
    elif actor:
        linkedin_id = actor.split(':')[-1]

    # URL du profil
    profile_url = ''
    if linkedin_id:
        profile_url = 'https://www.linkedin.com/in/{}'.format(linkedin_id)

    # Chercher le nom dans l'activite (varie selon l'API)
    first_name = (activity.get('firstName') or activity.get('first_name') or
                  activity.get('actorFirstName') or '')
    last_name  = (activity.get('lastName')  or activity.get('last_name')  or
                  activity.get('actorLastName')  or '')

    # Fallback : nom complet
    if not first_name:
        full = (activity.get('actorName') or activity.get('name') or
                activity.get('actorFullName') or '')
        if full and ' ' in str(full):
            parts = str(full).split(' ', 1)
            first_name, last_name = parts[0], parts[1]
        elif full:
            first_name = str(full)

    # Dernier fallback
    if not first_name:
        first_name = 'LinkedIn'
    if not last_name:
        last_name = linkedin_id or 'Contact'

    return {
        'profile_url': profile_url,
        'first_name':  first_name,
        'last_name':   last_name,
        'linkedin_id': linkedin_id,
    }


def post_reply(post_urn, text, parent_comment_urn):
    """
    Poste une reponse EN REPONSE a un commentaire (dans le thread).
    Utilise l'API REST sociale classique avec w_member_social.
    """
    encoded_urn = quote(post_urn, safe='')
    url = '{}/rest/socialActions/{}/comments'.format(BASE, encoded_urn)
    body = {
        "actor": _member_id(),
        "message": {"text": text},
        "parentComment": {"urn": parent_comment_urn}
    }
    headers = {
        'Authorization': 'Bearer {}'.format(os.getenv('LINKEDIN_ACCESS_TOKEN')),
        'Content-Type': 'application/json',
        'X-Restli-Protocol-Version': '2.0.0',
        'LinkedIn-Version': '202401',
    }
    r = requests.post(url, headers=headers, json=body)
    r.raise_for_status()
    return r.json()
