import hmac
import hashlib
import json
from typing import Union, Optional
from .types import WebhookEvent


def verify_webhook_signature(
        payload: Union[str, dict],
        signature: str,
        secret: str
) -> bool:
    """
    Verify webhook signature to ensure request is from InventPay.

    Args:
        payload: Raw request body (string or dict)
        signature: Signature from X-Webhook-Signature header
        secret: Your webhook secret from dashboard

    Returns:
        bool: True if signature is valid
    """
    try:
        if isinstance(payload, dict):
            payload_str = json.dumps(payload, separators=(',', ':'), sort_keys=True)
        else:
            payload_str = payload

        expected_signature = hmac.new(
            secret.encode('utf-8'),
            payload_str.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()

        return hmac.compare_digest(expected_signature, signature)

    except Exception as e:
        print(f"Webhook signature verification error: {e}")
        return False


def parse_webhook_event(
        payload: Union[str, dict],
        signature: str,
        secret: str
) -> Optional[WebhookEvent]:
    """
    Parse and validate webhook event.

    Args:
        payload: Webhook payload (string or dict)
        signature: Signature from header
        secret: Your webhook secret

    Returns:
        WebhookEvent if valid, None otherwise
    """
    if not verify_webhook_signature(payload, signature, secret):
        return None

    try:
        if isinstance(payload, str):
            payload_data = json.loads(payload)
        else:
            payload_data = payload

        if not all(key in payload_data for key in ['event', 'timestamp', 'data']):
            return None

        return WebhookEvent(
            event=payload_data['event'],
            timestamp=payload_data['timestamp'],
            data=payload_data['data']
        )

    except (json.JSONDecodeError, KeyError, TypeError) as e:
        print(f"Failed to parse webhook event: {e}")
        return None


def get_supported_webhook_events() -> list:
    """Get list of supported webhook events."""
    return [
        "payment.created",
        "payment.pending",
        "payment.confirmed",
        "payment.completed",
        "payment.underpaid",
        "payment.expired",
        "payment.failed",
        "payment.test",
        "withdrawal.completed",
        "withdrawal.failed",
        "withdrawal.processing",
    ]