o
    &f•j×'  ã                	   @   s¢  d dl Z d dlmZmZ d dlmZmZmZmZmZm	Z	 d dl
mZmZmZmZ d dlmZ d dlmZmZmZm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 d dl m!Z!m"Z"m#Z#m$Z$m%Z% d dl&m'Z' d dl(m)Z) eddgd�Z*eddgd�Z+e*j,deej-d�dedefdd„ƒZ.e*j/deej0d�eddd�e	eƒfde1de1dB de2dB fdd „ƒZ3e*j,d!ej0d"�de1fd#d$„ƒZ4e+j/d%ej0d"�d&e1fd'd(„ƒZ5dS ))é    N)ÚdatetimeÚtimezone)Ú	APIRouterÚRequestÚQueryÚstatusÚHTTPExceptionÚDepends)ÚSessionInitRequestÚSessionInitResponseÚSessionHistoryResponseÚMessageHistoryItem)Úget_tenant_by_site_id)Úcreate_sessionÚget_session_by_idÚupdate_session_statusÚ update_session_connection_status)Úget_conversation_by_session_idÚ%get_active_conversation_by_session_idÚget_conversation_by_id)Úget_messages_by_conversation_id)Úget_current_agent_optional)Úget_database)Úactive_sessionsÚadd_active_sessionÚbroadcast_to_agentsÚnotify_visitor_socketÚcancel_grace_period_timer)Úis_origin_allowed)Úextract_client_ipz/api/v1/sessionÚsession)ÚprefixÚtagsz/api/v1/conversationÚconversationz/init)Úresponse_modelÚstatus_codeÚpayloadÚrequestc                 Ã   s²   �t ƒ }t|| jƒI d H }|sttjd| j› d�d�‚|j d¡p&|j d¡}t||d ƒs=ttj	d|› d| j› d�d�‚t
|ƒ}| jrI| j ¡ nd }t|| j||d	�I d H }|S )
NzTenant not found for siteId 'ú'©r%   ÚdetailÚoriginÚrefererÚdomainzOrigin 'z ' is not authorized for siteId ')ÚdbÚsite_idÚ	user_dataÚ
ip_address)r   r   ÚsiteIdr   r   ÚHTTP_404_NOT_FOUNDÚheadersÚgetr   ÚHTTP_403_FORBIDDENr   ÚuserÚ
model_dumpr   )r&   r'   r.   Útenantr+   Ú	client_ipÚ	user_dictÚsession_doc© r=   ú4/web/html/dev/chatbot/backend/app/routers/session.pyÚinit_session&   s.   €þþür?   z/{sessionId}/historyz-Optional siteId for visitor access validation)ÚdefaultÚdescriptionÚ	sessionIdr2   Úauthenticated_agentc                 Ã   s¾  �t ƒ }t|| ƒI dH }|sttjd| › d�d�‚|s+|r$|| d¡kr+ttjdd�‚t|| ƒI dH }g }|rmt||d ƒI dH }|D ])}| d¡}	t	|	d	ƒrS|	 
¡ nt|	ƒ}
| t|d
 |d |d |
| d¡d�¡ qC| d¡}t	|d	ƒr{| 
¡ n|r�t|ƒnd}| d¡p�|r�| d¡nd}| d¡}	t | i ¡ d¡p¯t	|	d	ƒr¨|	 
¡ n|	r®t|	ƒnd}t|d |d | dd¡| dd¡| d¡||| d¡| dd¡||rÚ|d |d�S d|d�S )a"  
    Read-only endpoint to retrieve persisted session metadata and conversation message history from MongoDB.
    
    Security:
    - Authenticated agents (with Bearer JWT) can access any session.
    - Unauthenticated callers (visitor widget) must supply a matching siteId parameter.
    Nú	Session 'ú' not foundr)   r2   z!Access denied for session historyÚconversationIdÚ	createdAtÚ	isoformatÚ	messageIdÚroleÚcontentÚagentId©rI   rJ   rK   rG   rL   Ú
assignedAtÚendedByÚconnectedAtrB   r   ÚRINGINGÚmodeÚruleÚassignedAgentIdÚ	ipAddressÚcountryÚUnknown)rB   r2   r   rR   rT   rN   rO   rU   rV   rP   rF   Úmessages)r   r   r   r   r3   r5   r6   r   r   ÚhasattrrH   ÚstrÚappendr   r   r   )rB   r2   rC   r.   r    ÚconvÚmessages_listÚraw_messagesÚmÚcreated_at_valÚcreated_at_strÚassigned_at_valÚassigned_at_strÚended_byÚconnected_at_strr=   r=   r>   Úget_session_historyI   sd   €
þþ

û
"
4



ôôrf   z/{sessionId}/new-conversation)r%   c           
      Ã   sú  �t ƒ }t|| ƒI d H }|sttjd| › d�d�‚| dd¡}t|| ƒI d H }|r>| d¡dvr>| d¡dkr>ttjd	d�‚d
t 	¡ j
d d… › �}t tj¡}|| |d||dœ}|d  |¡I d H  t|| dƒI d H  t|| dd d�I d H  |d  d| id d dœddidœ¡I d H  t| ƒ d }| d¡s¡| d¡s¡| d¡r°| d¡| d¡| d¡dœ}t| |t | i ¡ d¡|| d¡| dd¡dd d dd d�}	td | ||ddd || d¡| dd¡|	d! d"d#œƒI d H  t| d$d|d%d&œƒI d H  | |dd'œS )(NrD   rE   r)   r2   Ú r   )ÚendedÚENDEDri   zTCannot start a new conversation while an active conversation exists for this sessionÚconv_é   Úopen)rF   rB   r2   r   rG   Ú	updatedAtÚconversationsrQ   Úonline)Údisconnected_atÚsessionsrB   )rT   rN   rO   )z$setz$unsetÚuserIdÚuserNameÚ	userEmail)ÚidÚnameÚemailÚ	websocketrU   rV   rW   )Ú
session_idr/   rx   r0   r1   rV   Ú
status_valÚassigned_agent_idÚassigned_atÚconnection_statusrp   Úvisitor_connectedrP   T)ÚtyperB   rF   r2   r   ÚconnectionStatusrT   r7   rU   rV   rP   ÚisNewConversationÚstatus_changedz"Waiting for an agent to connect...)r   r   rF   Úmessage)rB   rF   r   )r   r   r   r   r3   r5   r   ÚHTTP_400_BAD_REQUESTÚuuidÚuuid4Úhexr   Únowr   ÚutcÚ
insert_oner   r   Ú
update_oner   r   r   r   r   )
rB   r.   r    r/   Úactive_convÚconv_idrˆ   Úconv_docr0   Úactive_infor=   r=   r>   Ú create_new_conversation_endpoint‘   sœ   €
þþúþ
þý
õ
ôüýr�   z/{conversationId}rF   c              
   Ã   sÈ   �t ƒ }t|| ƒI d H }|sttjd| › d�d�‚t|| ƒI d H }g }|D ](}| d¡}t|dƒr5| ¡ nt	|ƒ}| 
|d |d |d || d	¡d
œ¡ q%|d |d |d | dd¡| d¡|dœS )NzConversation 'rE   r)   rG   rH   rI   rJ   rK   rL   rM   rF   rB   r2   r   rl   rO   )rF   rB   r2   r   rO   rX   )r   r   r   r   r3   r   r5   rY   rH   rZ   r[   )rF   r.   r\   r^   r]   r_   r`   ra   r=   r=   r>   Úget_conversation_by_id_endpointô   s6   €
þ

û	
úr‘   )6r…   r   r   Úfastapir   r   r   r   r   r	   Úapp.models.sessionr
   r   r   r   Ú"app.repositories.tenant_repositoryr   Ú#app.repositories.session_repositoryr   r   r   r   Ú(app.repositories.conversation_repositoryr   r   r   Ú#app.repositories.message_repositoryr   Úapp.dependencies.authr   Úapp.databaser   Úapp.services.presencer   r   r   r   r   Úapp.utils.origin_validatorr   Úapp.utils.ip_extractorr   ÚrouterÚconversation_routerÚpostÚHTTP_201_CREATEDr?   r5   ÚHTTP_200_OKrZ   Údictrf   r�   r‘   r=   r=   r=   r>   Ú<module>   s>     "
ýÿþýGb