"""
Payrix transaction submission utilities.

Submits a sale/charge to Payrix via `/txns` using a previously saved
Payrix payment method token, and returns a normalized transaction object.

Pure function style: no FastAPI request objects.
"""
from __future__ import annotations

import logging
from typing import Any, Dict, Optional

from src.core.payrix.http import payrix_request
from src.core.payrix.status_mapper import (
    map_payrix_payload_to_transaction_status,
    transaction_status_enum_to_string,
)

logger = logging.getLogger("payrix")



def _extract_body_field(body: Dict[str, Any], *keys: str) -> Any:
    for k in keys:
        if k in body:
            return body[k]
    return None


async def submit_payrix_charge(
    *,
    amount: float | int,
    currency: str,
    customer_id: int,
    payrix_token: str,
    payment_method_type: str = "card",
    merchant_id: Optional[int] = None,
    capture: bool = True,
) -> Dict[str, Any]:
    """
    Submit a payment transaction to Payrix `/txns` using a saved token.

    Args:
        amount: Transaction amount (as provided to Payrix)
        currency: ISO currency (e.g., "usd")
        customer_id: Internal customer id in our system
        payrix_token: The Payrix payment method token stored earlier
        payment_method_type: Payment method type ("card" or "ach")
        merchant_id: Optional internal merchant id for logging context
        capture: Whether to capture immediately (sale)

    Returns:
        Normalized dict: {transaction_id, status, amount, currency, raw_response}

    Raises:
        PayrixApiError: on non-2xx response, with status_code, error body, request_id
    """
    # Determine Payrix type based on payment method
    # 1 = Credit Card, 7 = ACH/Bank Account
    payrix_type = 1 if payment_method_type.lower() == "card" else 7
    
    payload: Dict[str, Any] = {
        "amount": amount,
        "currency": currency,
        "token": payrix_token,
        "capture": capture,
        "type": payrix_type,
        "origin": 2,  # Origin 2 for API transactions
        # Additional fields can be added per Payrix spec (like order/customer refs)
    }

    resp = await payrix_request(
        operation="create_txn",
        method="POST",
        path="/txns",
        json=payload,
        merchant_id=str(merchant_id) if merchant_id is not None else None,
        customer_id=str(customer_id),
        token="stored",
    )

    body: Dict[str, Any] = resp.json()

    txn_id = _extract_body_field(body, "id", "txnId", "transactionId")
    internal_status = map_payrix_payload_to_transaction_status(body)
    normalized_status = transaction_status_enum_to_string(internal_status)

    normalized: Dict[str, Any] = {
        "transaction_id": txn_id,
        "status": normalized_status,
        "amount": _extract_body_field(body, "amount") or amount,
        "currency": _extract_body_field(body, "currency") or currency,
        "raw_response": body,
    }

    logger.info(
        "provider=payrix op=%s status=%s merchant_id=%s customer_id=%s transaction_id=%s",
        "create_txn",
        normalized_status,
        str(merchant_id) if merchant_id is not None else "",
        str(customer_id),
        str(txn_id) if txn_id is not None else "",
    )

    return normalized
