import hmac
import hashlib
import json
import time
import httpx
import structlog
from app.db.postgres import db

logger = structlog.get_logger(__name__)

class WebhookDispatcher:
    """
    Dispatches webhook events to registered URLs.
    """
    
    @staticmethod
    async def dispatch(license_key: str, event: str, payload: dict):
        """
        Dispatch an event to all subscribed webhooks for a license.
        """
        # Fetch active webhooks for this license that subscribe to this event
        # Note: In a real app, we'd filter by event type in SQL or code
        webhooks = await db.fetch(
            "SELECT id, url, secret, events FROM webhooks WHERE license_key = $1 AND active = TRUE",
            license_key
        )
        
        if not webhooks:
            return
            
        logger.info("dispatching_webhooks", event=event, count=len(webhooks))
        
        async with httpx.AsyncClient(timeout=10.0) as client:
            for webhook in webhooks:
                # Check if webhook subscribes to this event
                if event not in webhook['events'].split(','):
                    continue
                    
                try:
                    await WebhookDispatcher._send_webhook(client, webhook, event, payload)
                except Exception as e:
                    logger.error("webhook_send_failed", url=webhook['url'], error=str(e))

    @staticmethod
    async def _send_webhook(client: httpx.AsyncClient, webhook: dict, event: str, payload: dict):
        """Send a single webhook request with HMAC signature."""
        timestamp = int(time.time())
        
        body = {
            'id': f"evt_{timestamp}",
            'event': event,
            'created_at': timestamp,
            'data': payload
        }
        
        json_body = json.dumps(body)
        
        # Calculate signature
        signature = hmac.new(
            webhook['secret'].encode('utf-8'),
            json_body.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        
        headers = {
            'Content-Type': 'application/json',
            'X-DataShaper-Signature': signature,
            'X-DataShaper-Event': event,
            'X-DataShaper-Timestamp': str(timestamp)
        }
        
        response = await client.post(webhook['url'], content=json_body, headers=headers)
        response.raise_for_status()
        
        logger.debug("webhook_sent", url=webhook['url'], status=response.status_code)
