import httpx
import time
import json
import logging
import hmac
import hashlib
from typing import Dict, Any
from sqlalchemy.orm import Session
from app.models.user import User
from app.models.mapping import AppUserMapping
from app.models.application import Application

logger = logging.getLogger(__name__)

class WebhookService:
    @staticmethod
    def _generate_signature(secret: str, payload: str, timestamp: int) -> str:
        """
        Generate X-UAP-Signature: HMAC-SHA256(secret, timestamp + "." + payload)
        """
        message = f"{timestamp}.{payload}"
        return hmac.new(
            secret.encode('utf-8'),
            message.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()

    @staticmethod
    async def send_notification(url: str, secret: str, event_type: str, user_data: Dict[str, Any]):
        timestamp = int(time.time())
        payload_dict = {
            "event_type": event_type, # ADD, UPDATE, DISABLE
            "timestamp": timestamp,
            "data": user_data
        }
        payload_json = json.dumps(payload_dict)
        signature = WebhookService._generate_signature(secret, payload_json, timestamp)

        headers = {
            "Content-Type": "application/json",
            "X-UAP-Signature": signature,
            "X-UAP-Timestamp": str(timestamp)
        }

        async with httpx.AsyncClient() as client:
            try:
                response = await client.post(url, content=payload_json, headers=headers, timeout=5.0)
                response.raise_for_status()
                logger.info(f"Webhook sent to {url}. Status: {response.status_code}")
            except Exception as e:
                logger.error(f"Failed to send webhook to {url}: {str(e)}")

    @staticmethod
    async def trigger_user_event(db: Session, user_id: int, event_type: str):
        """
        Finds all apps mapped to this user and sends webhooks if configured.
        """
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            return

        mappings = db.query(AppUserMapping).filter(AppUserMapping.user_id == user_id).all()
        
        for mapping in mappings:
            app = mapping.application
            if app.notification_url:
                # Construct data specific to the app (e.g. including mapped_key)
                user_data = {
                    "user_id": user.id,
                    "mobile": user.mobile,
                    "status": user.status,
                    "mapped_key": mapping.mapped_key
                }
                # Note: app.app_secret is used for signing. 
                # If app_secret is stored as hash, we technically CANNOT sign it securely 
                # unless we stored the plain secret or a separate webhook secret.
                # Per previous step, we changed Application to store plain `app_secret`.
                await WebhookService.send_notification(
                    app.notification_url, 
                    app.app_secret, 
                    event_type, 
                    user_data
                )

