
import json
import logging
import requests
from config.config_settings import ONESIGNAL_CONFIG

logger = logging.getLogger(__name__)

class OneSignalService:
    """
    Service to handle OneSignal Push Notifications via REST API.
    Uses 'External User ID' mapping to target specific users.
    """
    
    BASE_URL = "https://onesignal.com/api/v1/notifications"
    
    def __init__(self):
        # Load multiple configurations
        self.configs = []
        
        # Mobile Config
        if ONESIGNAL_CONFIG.get('app_id') and ONESIGNAL_CONFIG.get('rest_api_key'):
            self.configs.append({
                'app_id': ONESIGNAL_CONFIG.get('app_id'),
                'api_key': ONESIGNAL_CONFIG.get('rest_api_key'),
                'name': 'Mobile'
            })
            
        # Web Config
        if ONESIGNAL_CONFIG.get('web_app_id') and ONESIGNAL_CONFIG.get('web_rest_api_key'):
            self.configs.append({
                'app_id': ONESIGNAL_CONFIG['web_app_id'],
                'api_key': ONESIGNAL_CONFIG['web_rest_api_key'],
                'name': 'Web'
            })
            
        if not self.configs:
            logger.warning("No OneSignal credentials configured.")

    def _get_headers(self, api_key):
        return {
            "Content-Type": "application/json; charset=utf-8",
            "Authorization": f"Basic {api_key}"
        }

    def send_notification_to_users(self, user_ids, title, message, data=None):
        """Send notification to users across all configured apps."""
        if not self.configs:
            return {"error": "OneSignal not configured"}
            
        target_ids = [str(uid) for uid in user_ids]
        results = {}
        
        for config in self.configs:
            payload = {
                "app_id": config['app_id'],
                "include_aliases": {
                    "external_id": target_ids
                },
                "target_channel": "push",
                "headings": {"en": title},
                "contents": {"en": message},
                "data": data or {}
            }
            
            # Web requires specific URL handling sometimes, but generic data usually works
            if config['name'] == 'Web' and data and data.get('path'):
                # Optional: Add web_url if you want clicked notifications to open specific page directly
                # payload['url'] = f"https://ashlyaacademy.com{data['path']}"
                pass
                
            results[config['name']] = self._send_request(payload, config['api_key'])
            
        return results

    def send_notification_to_segment(self, segment, title, message, data=None):
        if not self.configs:
            return {"error": "OneSignal not configured"}
            
        results = {}
        for config in self.configs:
            payload = {
                "app_id": config['app_id'],
                "included_segments": [segment],
                "headings": {"en": title},
                "contents": {"en": message},
                "data": data or {}
            }
            results[config['name']] = self._send_request(payload, config['api_key'])
            
        return results

    def _send_request(self, payload, api_key):
        try:
            response = requests.post(
                self.BASE_URL, 
                headers=self._get_headers(api_key), 
                data=json.dumps(payload)
            )
            
            result = response.json()
            
            if response.status_code == 200 and "errors" not in result:
                logger.info(f"OneSignal Sent [{payload['app_id']}]: {result.get('id')}")
                # Log only once effectively or structure logging better? 
                # For now logging each successful send might be noisy but safe.
                self._log_to_db(payload)
                return {"success": True, "id": result.get('id')}
            else:
                logger.error(f"OneSignal Error [{payload['app_id']}]: {result}")
                return {"success": False, "error": result}
                
        except Exception as e:
            logger.error(f"Failed to send OneSignal: {str(e)}")
            return {"success": False, "error": str(e)}

    def _log_to_db(self, payload):
        """Helper to insert notification into notifications table"""
        try:
            from database import get_db_connection
            
            title = payload.get('headings', {}).get('en', 'Notification')
            message = payload.get('contents', {}).get('en', '')
            data = payload.get('data', {})
            
            # Determine user_ids (if single/list target)
            user_ids = []
            if 'include_aliases' in payload and 'external_id' in payload['include_aliases']:
                user_ids = payload['include_aliases']['external_id']
            
            # Extract related info
            related_type = data.get('type')
            related_id = data.get('id')  # e.g. topic_id or attempt_id
            
            if not user_ids:
                return # Can't log broadcast segments easily to individual users instantly
                
            conn = get_db_connection()
            cursor = conn.cursor()
            
            query = """
                INSERT INTO notifications 
                (user_id, title, message, type, related_id, related_type, is_read, created_at)
                VALUES (%s, %s, %s, %s, %s, %s, 0, NOW())
            """
            
            for uid in user_ids:
                cursor.execute(query, (
                    uid, title, message, 'system', related_id, related_type
                ))
                
            conn.commit()
            cursor.close()
            conn.close()
            
        except Exception as e:
            logger.error(f"Failed to log notification to DB: {str(e)}")

# Singleton instance
onesignal_service = OneSignalService()
