"""Merchant PostgreSQL + asyncpg example. No connection or API call at import.

Call only after raw-body signature verification OR an authenticated details GET.
The connection belongs to your merchant database; install the adjacent SQL there.
"""
from decimal import Decimal, InvalidOperation


async def accept_paid(conn, payment, *, event_id=None):
    """Commit before returning 2xx; let DB errors cause a retryable non-2xx.

    event_id: verified webhook ID; None: reconciliation via authenticated API.
    Validate header/payload event IDs before calling this function.
    For reconciliation also require merchant_wallet from the details response.
    """
    if payment.get('status') != 'PAID':
        raise ValueError('Payment is not PAID')
    if event_id is not None and (not isinstance(event_id, str) or not event_id):
        raise ValueError('Invalid event ID')
    if event_id is not None and payment.get('event_id') != event_id:
        raise ValueError('Event ID mismatch')
    try:
        amount = Decimal(str(payment['expected_amount']))
    except (KeyError, InvalidOperation):
        raise ValueError('Invalid amount') from None
    if not amount.is_finite() or amount <= 0:
        raise ValueError('Invalid amount')
    async with conn.transaction(isolation='read_committed'):
        # Lock the order: distinct events and reconciliation serialize too.
        order = await conn.fetchrow(
            'SELECT * FROM merchant_orders WHERE payment_id=$1 FOR UPDATE',
            payment.get('payment_id'),
        )
        if order is None or amount != order['expected_amount']:
            raise ValueError('Unknown order or amount mismatch')
        if event_id is None or 'merchant_wallet' in payment:
            if payment.get('merchant_wallet') != order['merchant_wallet']:
                raise ValueError('Wallet mismatch')
        if event_id is not None:
            inserted = await conn.fetchval(
                'INSERT INTO merchant_payment_events(event_id,order_id) '
                'VALUES($1,$2) ON CONFLICT(event_id) DO NOTHING RETURNING event_id',
                event_id, order['order_id'],
            )
            if inserted is None:
                previous = await conn.fetchval(
                    'SELECT order_id FROM merchant_payment_events WHERE event_id=$1',
                    event_id,
                )
                if previous != order['order_id']:
                    raise ValueError('Event belongs to another order')
        if order['accepted_at'] is not None:
            return 'already_accepted'
        if order['fulfilment_mode'] == 'local':
            # Local business action in the SAME transaction as event insertion.
            await conn.execute(
                'INSERT INTO merchant_entitlements(order_id) VALUES($1)',
                order['order_id'],
            )
        else:
            # No external network call inside this transaction.
            await conn.execute(
                'INSERT INTO merchant_delivery_jobs(order_id,idempotency_key) '
                'VALUES($1,$2)', order['order_id'], 'fulfil:' + order['order_id'],
            )
        await conn.execute(
            'UPDATE merchant_orders SET accepted_at=now() WHERE order_id=$1',
            order['order_id'],
        )
    return 'accepted'
