from exponent_server_sdk import (
    DeviceNotRegisteredError,
    PushClient,
    PushMessage,
    PushServerError,
    PushTicketError,
)
import requests
from requests.exceptions import ConnectionError, HTTPError
import os 
# Configure requests to use a session for performance
# IMPORTANT: When passing a custom session to PushClient, we MUST provide the JSON headers
session = requests.Session()
session.headers.update({
    'accept': 'application/json',
    'accept-encoding': 'gzip, deflate',
    'content-type': 'application/json',
    'authorization': f'Bearer ARfhsPAlW0zlZ5za_IpJa2hJQZoT_d7whdlOfoAX',
})

def send_push_message(token: str, title: str, message: str, extra=None, category=None):
    """
    Send a push message to a device using Expo's Push Notification Service.
    
    :param token: The Expo push token for the device.
    :param title: Title of the push notification.
    :param message: Body of the push notification.
    :param extra: Optional dictionary with extra data payload.
    :param category: Optional category ID for interactive notifications.
    :return: True if successful, False if the token is invalid or another error occurred.
    """
    if extra is None:
        extra = {}

    try:
        msg = PushMessage(to=token, title=title, body=message, data=extra, category=category)
        
        # Monkey patch get_payload to include image if it exists in extra
        original_get_payload = msg.get_payload
        def custom_get_payload():
            payload = original_get_payload()
            if extra and 'image' in extra:
                payload['image'] = extra['image']
            return payload
        msg.get_payload = custom_get_payload

        response = PushClient(session=session).publish(msg)
    except PushServerError as exc:
        # Encountered some likely formatting/validation error.
        print(f"PushServerError: {exc.errors}")
        return False
    except (ConnectionError, HTTPError) as exc:
        # Encountered some Connection or HTTP error - retry a few times in production
        print(f"Connection/HTTP Error sending push: {exc}")
        return False

    try:
        # We got a response back, but we don't know whether it's an error yet.
        response.validate_response()
    except DeviceNotRegisteredError:
        # Mark the push token as inactive in DB (handle gracefully)
        print(f"DeviceNotRegisteredError: token {token} is no longer registered.")
        return False
    except PushTicketError as exc:
        # Encountered some other per-notification error.
        print(f"PushTicketError: {exc.message} - details: {getattr(exc.push_response, 'details', None)}")
        return False

    return True

