
    Di~                       d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ  ej0                  d      ZddZddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 	 	 ddZy)u  
Utilities for creating payment methods via Worldpay Payrix Pro.

Flow: Frontend iframe produces a temporary method token → we POST to
Payrix `/tokens` to create/save a token record → normalize fields and
persist a `PaymentMethod` + `PaymentMethodCardDetails` in our DB.

This module is pure (no FastAPI request objects). It accepts an
SQLAlchemy `Session` and necessary identifiers.
    )annotationsN)AnyDictOptional)Session)select)ValidationExceptionPayrixApiError)payrix_request)PaymentMethodTypesPaymentMethodScopes)PaymentMethod)PaymentMethodCardDetailspayrixc                    | xs i j                  d      xsC | xs i j                  d      xs, | xs i j                  d      xs | xs i j                  d      }d|dS )a   
    Normalize Payrix token response into our standard shape.

    Note: Card meta (brand, last4, exp_month, exp_year) is provided by the
    frontend and not by Payrix for token lookups, so we do not attempt to
    extract those fields here. They are set to None and overlaid later.
    idtokenIdtoken	referencer   )providerprovider_payment_method_id)get)bodyr   s     c/var/www/html/hwPaymentPortal-be-dev/hw-payment-portal-api/src/apps/payment_methods/utils/payrix.py_normalize_payrix_tokenr      st     
 	)JBI&	)JBG$	) JBK(	  &@     )customer_idpayer_idpayment_request_idbilling_infoc          	       K   |rt        |t              st        d      t        dddd|it        |      d       d	{   }|j	                         }t        |      }|r|j                  d
      ||d
<   |j                  d      st        d|d      t        |j                  d            }	| j                  t        t              j                  t        j                  |	k(              j                         }
|
r|S |||S t        |j                  d      |j                  d      rt        |j                  d            nd	|j                  d      rt        |j                  d            nd	|	      }| j                  |       | j                          t         j"                  |	dt$        j&                  |||j(                  d}|||d<   t        di |}| j                  |       | j+                          |S 7 w)a  
    Create and persist a payment method using a frontend Payrix iframe token.

    - Validates required input.
    - Calls Payrix `/tokens` to create/save the payment method token.
    - Normalizes the response and persists card details + payment method.

    Args:
        session: SQLAlchemy session (already configured and managed by caller)
        token: Iframe token from frontend
        merchant_id: Merchant identifier in our system
        customer_id: Customer identifier in our system
        payer_id: Optional payer/contact id
        payment_request_id: Optional payment request id
        billing_info: Optional fallback billing info to attach in normalized output

    Returns:
        A normalized dict with fields: provider, provider_payment_method_id,
        brand, last4, exp_month, exp_year, billing.

    Raises:
        ValidationException: if required inputs are missing
        PayrixApiError: if Payrix returns a non-2xx response
    &Token is required and must be a stringmessagecreate_tokenPOSTz/tokensr   provided)	operationmethodpathjsonr   r   Nbillingr   z(Payrix did not return a token identifierr   )r$   errormodulebrand	exp_monthexp_year)r/   expire_monthexpire_yearreference_idT)r)   payment_method_idis_connectedscoper   r   card_details_idr    )
isinstancestrr	   r   r+   r   r   executer   r   wherer5   scalar_one_or_noner   addflushr   CARDr   MERCHANTr   commit)sessionr   r   r   r   r    respr   
normalizedprovider_idexisting_pmcard	pm_kwargspms                 r   'create_payment_method_from_iframe_tokenrL   4   s    D 
5#.!*RSS   u$ D  99;D(.J
y19 ,
9>>67!>
 	
 jnn%ABCK//}##M$C$C{$RS    h. $nnW%9C9TS45Z^7A~~j7QC
z23W[ 	D KKMMO %))($--"77	I %*<	&'		#	#BKKONN _s   >H HGH)r   c          	       K   |rt        |t              st        d      t        ddd| t        |      |t        |      nd       d{   }|j	                         }t        d|       d}t        |t              rod	|v rk|j                  d	      xs i }|j                  d
      xs g }t        d|       t        |t              r%t        |      dkD  r|d   }	t        |	t              r|	}t        ||      }
|
S |      }
|
S 7 w)a  
    Retrieve details of a previously created Payrix token.

    This uses a GET call to the token resource and normalizes the response
    into our standard format without persisting anything to the database.

    Args:
        session: SQLAlchemy session (unused, kept for signature consistency)
        token: The token id/reference generated on the frontend
        merchant_id: Merchant identifier (used for auditing/routing on Payrix)
        customer_id: Optional customer identifier for logging/routing

    Returns:
        Normalized dict with provider, provider_payment_method_id, brand, last4,
        exp_month, exp_year, billing.
    r"   r#   	get_tokenGETz/tokens/N)r(   r)   r*   merchant_idr   z#Payrix Token Details Response Body:responsedataz
Data List:r   )r:   r;   r	   r   r+   printdictr   listlenr   )rD   r   rP   r   rE   r   	data_noderesp_obj	data_listfirstrF   s              r   get_payment_token_detailsr[      s    . 
5#.!*RSSw$(3(?C$T D  99;D	
/6'+I$*"488J'-2LL(.B	lI&i&3y>A+=aLE%&!	(i6KVJ RVVJ/s   ADDB9D)r   Dict[str, Any]returnr\   )rD   r   r   r;   r   Optional[int]r   r^   r   r^   r    zOptional[Dict[str, Any]]r]   r\   )
rD   r   r   r;   rP   intr   r^   r]   r\   )__doc__
__future__r   loggingtypingr   r   r   sqlalchemy.ormr   
sqlalchemyr   src.core.exceptionsr	   r
   src.core.payrix.httpr   src.core.utils.enumsr   r   /src.apps.payment_methods.models.payment_methodsr   ;src.apps.payment_methods.models.payment_method_card_detailsr   	getLoggerloggerr   rL   r[   r9   r   r   <module>rm      s   	 #  & & "  C / H I 
		8	$6 "&"(,-1uu u
 u u &u +u uz "&11 1 	1
 1 1r   