"""
Utility helpers for django_stripe_billing.
"""
from __future__ import annotations

import logging

import requests
from django.utils import timezone

from .conf import stripe_billing_settings

logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# Currency helpers
# ---------------------------------------------------------------------------

def str_to_number(num: int | str) -> str:
    """
    Convert Stripe integer amount to decimal string (e.g. 1234 -> '12.34').

    Handles small amounts correctly: 0 -> '0.00', 5 -> '0.05'.
    """
    s = str(num).strip()
    if not s or (s.startswith('-') and len(s) == 1):
        return '0.00'
    if len(s) <= 2:
        s = s.zfill(3)  # 5 -> 005, 0 -> 000
    return s[:-2] + '.' + s[-2:]


def number_to_currency(num, currency: str = 'gbp') -> str:
    """
    Format a Stripe integer amount as a human-readable currency string.

    Args:
        num: Amount in smallest currency unit (e.g. pence / cents).
        currency: ISO-4217 currency code (case-insensitive).

    Returns:
        Formatted string, e.g. '£12.34', '$9.99', '€5.00'.
    """
    symbols = {
        'usd': '$',
        'gbp': '£',
        'eur': '€',
        'cad': 'CA$',
        'aud': 'AU$',
    }
    symbol = symbols.get(currency.lower(), currency.upper() + ' ')
    return f'{symbol}{str_to_number(num)}'


# ---------------------------------------------------------------------------
# Outgoing webhook (Zapier / Make / n8n)
# ---------------------------------------------------------------------------

def fire_outgoing_webhook(event_type: str, payload: dict) -> None:
    """
    POST a JSON payload to an outgoing webhook URL configured per event type.

    Reads URLs from ``STRIPE_BILLING['OUTGOING_WEBHOOK_URLS']`` (a dict
    mapping Stripe event type strings to URLs).  If the URL is empty/unset
    this is a no-op.

    The following fields are automatically added to every payload:

    - ``event_type`` — the Stripe event type string
    - ``timestamp`` — ISO-8601 UTC timestamp
    - ``environment`` — value of ``STRIPE_BILLING['ENVIRONMENT']``

    Args:
        event_type: Stripe event type (e.g. ``'invoice.payment_failed'``).
        payload: Arbitrary dict of data to include in the POST body.
    """
    webhook_urls: dict = stripe_billing_settings.OUTGOING_WEBHOOK_URLS
    url: str = webhook_urls.get(event_type, '')

    if not url:
        return

    payload = dict(payload)  # shallow copy — don't mutate caller's dict
    payload['event_type'] = event_type
    payload['timestamp'] = timezone.now().isoformat()
    payload['environment'] = stripe_billing_settings.ENVIRONMENT

    app_title = stripe_billing_settings.APP_TITLE or 'DjangoStripeBilling'
    user_agent = f'{app_title}-Webhook/1.0'

    try:
        resp = requests.post(
            url,
            json=payload,
            headers={'Content-Type': 'application/json', 'User-Agent': user_agent},
            timeout=10,
        )
        resp.raise_for_status()
        logger.info(
            '[OUTGOING WEBHOOK] %s sent to %s (HTTP %s)', event_type, url, resp.status_code
        )
    except requests.exceptions.Timeout:
        logger.warning('[OUTGOING WEBHOOK] %s timed out for %s', event_type, url)
    except requests.exceptions.RequestException as exc:
        logger.error('[OUTGOING WEBHOOK] %s failed for %s: %s', event_type, url, exc)
    except Exception as exc:  # noqa: BLE001
        logger.error('[OUTGOING WEBHOOK] %s unexpected error for %s: %s', event_type, url, exc)
