o
    ›k•j.  ã                	   @   sÔ   U d dl m Z mZ d dlmZmZ d dlmZmZmZ i Z	ee
ee
ef f ed< h d£Zde
de
fdd	„Zdde
de
de
d
B dd
fdd„Zde
dedd
fdd„Zde
dedd
fdd„Zdde
de
dd
fdd„Zd
S )é    )ÚdatetimeÚtimezone)ÚDictÚAny)Úactive_sessionsÚbroadcast_to_agentsÚnotify_visitor_socketÚactive_calls>   ÚIDLEÚENDEDÚRINGINGÚACCEPTEDÚREJECTEDÚ	CONNECTEDÚ
CONNECTINGÚCALL_REQUESTEDÚ
session_idÚreturnc                 C   s   t  | ¡}|r| dd¡S dS )zGReturns the current video call state for a session, defaulting to IDLE.Ústater
   )r	   Úget)r   Úcall© r   ú=/web/html/dev/chatbot/backend/app/services/video_signaling.pyÚget_call_state   s   
r   Nr   Úagent_idc                 C   sJ   |t vrdS t tj¡ ¡ }|dv rt | d¡ dS | |||dœt| < dS )z/Updates the in-memory video call state machine.N)r
   r   r   )Ú	sessionIdr   ÚagentIdÚ	updatedAt)ÚVALID_STATESr   Únowr   ÚutcÚ	isoformatr	   Úpop)r   r   r   Únow_isor   r   r   Úset_call_state   s   ür$   Úpayloadc                 Ã   s*  �|  d¡}|s
dS td|› d| › �ƒ td| › �ƒ t  | ¡}|r'|  d¡nd}|r0|  d¡nd}|r:|dks:|skd	d
lm} d	dlm} |ƒ }|durk||| ƒI dH }	|	rk|	  d¡}|	  d¡}|rk||d< ||d< td|› �ƒ |dkr�td| › d|› d�ƒ t| d| ddœƒI dH  dS |s§td| › d�ƒ t| d| ddœƒI dH  dS t| ƒ}
|dv �r|
dv rÂt| d| ddœƒI dH  dS t	| d|ƒ d| |rÑ|  d¡nd|rÙ|  d¡nd|  d¡pã|  d¡dd œ}td!| › �ƒ td"|› �ƒ td#|› �ƒ t
||gd$�I dH  dS |d%v �r5t	| d&|ƒ d'| |  d(¡�p|  d¡d)œ}td*|› �ƒ t
||gd$�I dH  dS |dk�rUt	| d+ƒ d| |  d,d-¡dœ}t
||gd$�I dH  dS |d.k�rwd.| |  d/¡d0d1œ}td2|› �ƒ t
||gd$�I dH  dS |d3k�r“t	| d4ƒ d3| dd5œ}t
||gd$�I dH  dS dS )6z™
    Handles WebRTC signaling messages dispatched from a visitor WebSocket.
    Validates session state and forwards payloads to the assigned agent.
    ÚtypeNz1[VIDEO DEBUG] visitor video event received: type=z, sessionId=z[VIDEO DEBUG] sessionId=ÚstatusÚassignedAgentIdÚIN_CHATr   ©Úget_database©Úget_session_by_idz[VIDEO DEBUG] assignedAgentId=z [VIDEO DEBUG] Rejected call for z: status is z (not IN_CHAT)Úvideo_call_rejectedz3Video calling requires an active chat with an agent©r&   r   Úreasonz: no assigned agentz!No agent assigned to this session©Úvideo_call_requestedÚwebrtc_offer)r   r   r   r   r   z#A video call is already in progressr   r2   ÚsiteIdÚ ÚuserÚofferÚsdpÚvisitor)r&   r   r4   r6   r7   Úsenderz-[VIDEO] visitor request received for session z[VIDEO] assigned agent = z$[VIDEO] forwarding request to agent ©Útarget_agent_ids©Úvideo_call_acceptedÚwebrtc_answerr   r?   Úanswer©r&   r   r@   z#[VIDEO] forwarding answer to agent r   r0   zVisitor declined the video callÚwebrtc_ice_candidateÚ	candidateÚagent©r&   r   rC   Útargetz*[VIDEO] forwarding ICE candidate to agent Úvideo_call_endedr   ©r&   r   ÚendedBy)r   Úprintr   Úapp.databaser+   Ú#app.repositories.session_repositoryr-   r   r   r$   r   )r   r%   Úmsg_typeÚsessionÚ
status_valÚassigned_agent_idr+   r-   ÚdbÚ
db_sessionÚcurrent_stateÚforward_payloadr   r   r   Úhandle_visitor_signaling-   s´   €



ýý
ýú
ý


ý
ü

ýùrU   c              	   Ã   s,  �|  d¡}|  d¡}tdƒ td|› �ƒ td|› �ƒ td| › �ƒ |r(|s*dS t  |¡}|r6|  d¡nd}|sbd	d
lm} d	dlm} |ƒ }|durb|||ƒI dH }	|	rb|	  d¡}|rb||d< td|› d|› d|rq|  d¡nd› �ƒ |r‰|| kr‰td|› d| › d�ƒ dS |dv r¬t|d| ƒ d||  d¡pž|  d¡ddœ}
t||
ƒI dH  dS |dv rÎt|d| ƒ d||  d¡pÁ|  d¡dœ}
t||
ƒI dH  dS |d krët|d!ƒ d ||  d"d#¡d$œ}
t||
ƒI dH  dS |d%k�rd%||  d&¡d'd(œ}
t||
ƒI dH  dS |d)k�rt|d*ƒ d)|dd+œ}
t||
ƒI dH  dS |d,v �r’|  d-¡�p-|  d.¡}|�r”d	d/l	m
} d	d0lm} d	d1lm} d	d
lm} |ƒ }|�rU|  d2d3¡nd3}||||ƒI dH }|d4 }||||d|| d5�I dH }t|d6||d7 |d8œƒI dH  |d6||| |d7 |d9œƒI dH  dS dS dS ):zž
    Handles WebRTC signaling messages dispatched from an agent WebSocket.
    Validates agent assignment and forwards payloads to the visitor WebSocket.
    r&   r   z,[VIDEO][TRACE][BACKEND] received agent eventz[VIDEO][TRACE][BACKEND] type = z$[VIDEO][TRACE][BACKEND] sessionId = z"[VIDEO][TRACE][BACKEND] agentId = Nr(   r   r*   r,   z/[VIDEO][TRACE][BACKEND] session doc: sessionId=z, assignedAgentId=z	, status=r'   Únonez8[VIDEO][TRACE][BACKEND] Security check failed: assigned=z	, sender=z - droppingr1   r   r2   r7   r8   rD   )r&   r   r7   r:   r=   r   r?   r@   rA   r.   r   r0   zAgent declined the video callr/   rB   rC   r9   rE   rG   r   rH   )Úagent_messageÚmessageÚchat_messagerX   Úcontent)Úget_or_create_conversation)Úcreate_message)r   r4   r5   ÚconversationId)Úconversation_idr   ÚrolerZ   r   rW   Ú	messageId)r&   r   r`   rX   )r&   r   r4   r(   r`   rX   )r   rJ   r   rK   r+   rL   r-   r$   r   Ú(app.repositories.conversation_repositoryr[   Ú#app.repositories.message_repositoryr\   Úapp.services.presencer   )r   r%   rM   r   rN   rP   r+   r-   rQ   rR   rT   rZ   r[   r\   r   Úsite_idÚconversationr^   Úmsg_docr   r   r   Úhandle_agent_signalingŸ   sÀ   €



(üý

ý
ü

ý
úüúçrg   Ú
chat_endedr0   c                 Ã   sv   �| t v r9t  | d¡}|r| d¡nd}d| |dœ}t| |ƒI dH  |r0t||gd�I dH  dS t|ƒI dH  dS dS )zV
    Cleans up any active video call for a session when chat ends or disconnects.
    Nr   rG   r/   r;   )r	   r"   r   r   r   )r   r0   Ú	call_infor   Ú	end_eventr   r   r   Úterminate_video_call  s   €ýórk   )N)rh   )r   r   Útypingr   r   rc   r   r   r   r	   ÚstrÚ__annotations__r   r   r$   ÚdictrU   rg   rk   r   r   r   r   Ú<module>   s    	 rr