# subscriptions/paystack.py
"""
Paystack payment gateway integration for SwiftPOS subscriptions.
API docs: https://paystack.com/docs/api/

Handles:
- Initialize transaction (get checkout URL)
- Verify transaction (server-side HMAC verification)
- Webhook signature validation
"""

import hashlib
import hmac
import logging
import requests

from django.conf import settings

logger = logging.getLogger(__name__)

PAYSTACK_BASE_URL = "https://api.paystack.co"


def _get_secret_key():
    key = getattr(settings, 'PAYSTACK_SECRET_KEY', '')
    if not key:
        raise ValueError("PAYSTACK_SECRET_KEY is not configured in settings.")
    return key


def _headers():
    return {
        "Authorization": f"Bearer {_get_secret_key()}",
        "Content-Type": "application/json",
    }


# ─────────────────────────────────────────────────────────────
# INITIALIZE TRANSACTION
# ─────────────────────────────────────────────────────────────

def initialize_transaction(amount_naira, email, reference, callback_url, metadata=None):
    """
    Initialize a Paystack transaction.
    Returns the authorization_url to redirect the customer to.

    Args:
        amount_naira: Decimal amount in Naira (e.g. Decimal('5000.00'))
        email: Customer email string
        reference: Our unique PaymentTransaction.payment_reference
        callback_url: URL Paystack redirects to after payment
        metadata: Optional dict of extra data to attach

    Returns dict: {
        'authorization_url': str,
        'access_code': str,
        'reference': str,
    }
    Raises ValueError on API error.
    """
    # Paystack expects amount in KOBO (multiply by 100)
    amount_kobo = int(float(amount_naira) * 100)

    payload = {
        "email": email,
        "amount": amount_kobo,
        "reference": reference,
        "callback_url": callback_url,
        "currency": "NGN",
        "metadata": metadata or {},
    }

    try:
        resp = requests.post(
            f"{PAYSTACK_BASE_URL}/transaction/initialize",
            json=payload,
            headers=_headers(),
            timeout=15,
        )
        data = resp.json()
    except Exception as e:
        logger.error(f"Paystack initialize_transaction network error: {e}")
        raise ValueError(f"Paystack connection failed: {e}")

    if not data.get("status"):
        msg = data.get("message", "Unknown Paystack error")
        logger.error(f"Paystack API error: {msg}")
        raise ValueError(f"Paystack: {msg}")

    return data["data"]  # contains authorization_url, access_code, reference


# ─────────────────────────────────────────────────────────────
# VERIFY TRANSACTION
# ─────────────────────────────────────────────────────────────

def verify_transaction(reference):
    """
    Server-side verification of a completed transaction.
    DO NOT trust client-side success — always call this.

    Returns the full transaction data dict from Paystack.
    Raises ValueError if not paid or API error.
    """
    try:
        resp = requests.get(
            f"{PAYSTACK_BASE_URL}/transaction/verify/{reference}",
            headers=_headers(),
            timeout=15,
        )
        data = resp.json()
    except Exception as e:
        logger.error(f"Paystack verify_transaction network error: {e}")
        raise ValueError(f"Paystack verification failed: {e}")

    if not data.get("status"):
        raise ValueError(data.get("message", "Paystack verification failed"))

    return data["data"]  # contains status, amount, reference, paid_at, etc.


# ─────────────────────────────────────────────────────────────
# WEBHOOK SIGNATURE VALIDATION
# ─────────────────────────────────────────────────────────────

def validate_webhook_signature(raw_body: bytes, signature_header: str) -> bool:
    """
    Validate Paystack webhook HMAC-SHA512 signature.
    Paystack sends the signature in the 'x-paystack-signature' header.
    """
    try:
        secret = _get_secret_key().encode('utf-8')
        expected = hmac.new(secret, raw_body, digestmod=hashlib.sha512).hexdigest()
        return hmac.compare_digest(expected, signature_header)
    except Exception as e:
        logger.error(f"Paystack webhook signature validation error: {e}")
        return False
