o
    cBj<4                     @   sr  d Z ddlZddl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mZmZ eeZeedddZdad	d
 ZdefddZde
de
fddZdeeee
f  deee
f fddZdeee
f deee
f fddZdee deee ee ee f fddZdedeg e
f deee
f de
fddZdd d!d"ed#ee d$ee d%ee d&ed'edeee
f fd(d)Zd*eeeee
f   deee
f fd+d,Z d"ed-edeee
f fd.d/Z!		d6d"edeeee
f  dee deee
f fd0d1Z"		d6d"edeeee
f  dee deee
f fd2d3Z#		d6d"edeeee
f  dee deee
f fd4d5Z$dS )7uc   Live PCA panel data for MCube AI — mirrors dashboard stats, analytics, agents, calls, objections.    N)datedatetime	timedeltatimezone)Decimal)AnyCallableDictListOptionalTuple      )hoursminutesc                     sB   t d u rddlm  ddlm}   fddt D }| |a t S )Nr   Config)DatabaseHandlerc                    s    i | ]}|  r|t |qS  )isuppergetattr).0keyr   r   =/home/aiteam/pcaa-dev/dashboard-backend/mcube_ai_analytics.py
<dictcomp>   s     z_get_db.<locals>.<dictcomp>)_db_handlerconfigr   
db_handlerr   dir)r   cfgr   r   r   _get_db   s   r    returnc                   C   s   t t S N)r   now_ISTr   r   r   r   r   
_ist_today   s   r%   valuec                 C   sd   t | ttfr|  S t | trt| S t | tr"dd |  D S t | tt	fr0dd | D S | S )Nc                 S   s   i | ]	\}}|t |qS r   
_serializer   kvr   r   r   r   $       z_serialize.<locals>.<dictcomp>c                 S   s   g | ]}t |qS r   r'   )r   r+   r   r   r   
<listcomp>&       z_serialize.<locals>.<listcomp>)

isinstancer   r   	isoformatr   floatdictitemslisttuple)r&   r   r   r   r(      s   

r(   statsc                 C   s   | si S t t| dpdt| dpdt| dpdt| dp$dt| dp,dt| dp4dt| dp<dt| d	pDd| d
d urXtt| d
pTddnd t| dp`dt| dphd| ddS )Ntotal_callsr   answered_totalinbound_totaloutbound_totalinbound_answeredoutbound_answeredinbound_not_answeredoutbound_not_answeredavg_quality_score   analyzed_totalavg_answered_durationtalk_listen_ratio)r7   r8   r9   r:   r;   r<   r=   r>   r?   rA   rB   rC   )r(   intgetroundr1   )r6   r   r   r   _compact_stats*   s&   rG   metadatac                 C   s   | pi }| d}| d}| d}| d}t|trC| dp#i }|s+| d}|p6| dp6| d}|pB| dpB| d}|||| d| d	d
S )N	groupname	date_fromdate_tosnapshotfiltersdateFromdateTo
active_tab
route_path)rI   rJ   rK   rP   rQ   )rE   r/   r2   )rH   metarI   rJ   rK   rL   rM   r   r   r   _extract_filtersA   s"   





rS   messagec                 C   s   t | pd }| sdS t }td|r | }||dfS td|r4|tdd  }||dfS td	|rH|td
d  | dfS td|r]|jdd}| | dfS dS )z(Map user wording to a date range in IST. )NNNz	\btoday\btodayz\byesterday\b   days	yesterdayz<\bthis week\b|\blast 7 days\b|\bpast week\b|\bthis week'?s\b   last_7_daysz \bthis month\b|\bcurrent month\b)day
this_month)	strlowerstripr%   researchr0   r   replace)rT   textrV   dstartr   r   r   _detect_period_from_messageV   s    

rh   labelfnfactsc              
   C   sR   z| W S  t y( } ztd| | t||di | < W Y d }~d S d }~ww )Nzpanel_data %s failed: %serrors)	Exceptionloggerwarningr_   
setdefault)ri   rj   rk   excr   r   r   	_safe_runk   s   rr   T
   )include_agentsagent_limitbidrI   rJ   rK   rt   ru   c          
      C   sX   t | ||||}|||d}|r*| j|||||d}	|	pg |d< |	r*|	d |d< |S )N)rJ   rK   r6   limitagent_call_countsr   top_agent_by_call_volume)rG   get_location_statsget_agent_call_counts)
dbrv   rI   rJ   rK   rt   ru   r6   bundleagentsr   r   r   _period_bundlet   s   

r   rowsc                 C   sR   i }| s|S | D ]}t |dpd }||dt|dp!d ||< q|S )N	sentimentunknownr   count)r_   rE   r`   rD   )r   totalsrowr   r   r   r   _summarize_sentiment   s   $r   call_idc           	      C   s   t  }t| } t|}d|ddt  dd}t|| |p i }t|| |p*i }t|| |p4i }t|| |p>i }t|	dpGd}t
|dkr]|d d d	 |d< d
|d< ||d< ||d< ||d< ||d< |S )Ncall_detaildatabase_live_queryAsia/Kolkata)r   	today_ist)scoper   source	reference
transcriptrU   ip  z...(truncated)Ttranscript_truncatedcall	analyticsbant)r    r_   r%   r0   r(   get_call_by_idget_call_analyticsget_bant_analysisget_call_transcriptrE   len)	rv   r   r}   rk   r   r   r   transcript_objtranscript_textr   r   r   build_call_detail_panel_data   s.   
r   c              	      sN  t |pi }t t  |d|d}|d}t }| |tdd  }|tdd  }ddd	tt	
d
ddd | D dd}	i }
t |
d< t ||dd|
d< t ||
d< t dd|
d< |s~|rt |||
d< |
|	d< t|\}}}|rd|it ||dd|	d< ||td fdd|	}|rt||	d< td  fd!d|	}|r||	d < td" fd#d|	}|r||	d"< |d$ |	d%< td& fd'd|	}|r|dd |	d&< |d$ |	d(< td) fd*d|	}|r!||	d)< td+ fd,d|	}|r=|p6g dd |	d+< td- fd.d|	}|rY|pRg dd |	d-< td/ fd0d|	}|rzt|dd1 |	d/< t||	d2< td3 fd4d|	}|r|pg dd |	d3< td5 fd6d|	}|r|pg dd |	d5< td7 fd8d|	}|r|pg dd9 |	d7< td: fd;d|	}|rt|tr|n|d<pg }|dd |	d:< |r|d$ |	d=< td> fd?d|	}|r%t|tr|n|d<pg }|dd9 |	d>< |	S )@zOFull dashboard panel context with explicit today / all-time / filtered periods.rI   rJ   rK   rW   rX   r[   	dashboardr   r   z%Y-%m-%d %H:%M:%S)r   r   now_istc                 S   s   i | ]	\}}|r||qS r   r   r)   r   r   r   r      r,   z.build_dashboard_panel_data.<locals>.<dictcomp>u   Use periods.today for 'today' questions, periods.all_time for lifetime totals, and question_focus when the user asks about a specific time range. Never invent call counts — use stats and agent_call_counts from this data.)r   r   r   rM   noterV   F)rt   rZ   r\   Nall_timedashboard_filterperiodsri      )ru   question_focusdashboard_statsc                           S r"   )r{   r   rv   r}   rI   primary_from
primary_tor   r   <lambda>       z,build_dashboard_panel_data.<locals>.<lambda>analytics_overviewc                         t  S r"   )r(   get_analytics_overviewr   r   r   r   r      r.   ry   c                      s   j  ddS )N   rw   )r|   r   r   r   r   r     r.   r   rz   agent_quality_leaderboardc                      r   r"   )get_agent_leaderboardr   r   r   r   r     r   top_agent_by_quality_scorequality_by_agentc                      r   r"   )r(   get_quality_by_agentr   r   r   r   r     r.   call_purposesc                      r   r"   )r(   get_call_purpose_frequencyr   r   r   r   r     r.   objections_and_concernsc                      r   r"   )r(   get_concerns_frequencyr   r   r   r   r   %  r.   sentiment_by_locationc                      r   r"   )get_sentiment_by_locationr   r   r   r   r   -  r   r   sentiment_totalsquality_by_locationc                      r   r"   )r(   get_quality_by_locationr   r   r   r   r   6  r.   busy_locationsc                      r   r"   )r(   get_busy_locationsr   r   r   r   r   >  r.   groupsc                      s
     S r"   )get_all_groupnamesr   )rv   r}   r   r   r   D  s   
    recent_callsc                      s   t j d d dddS )Nr   r   rx   offsetrJ   rK   r(   get_filtered_raw_callsr   r   r   r   r   J      callslatest_calltoday_callsc                      s   t j d d dddS )Nr   r   r   r   r   )rv   r}   rI   	today_strr   r   r   `  r   )rS   r    r_   rE   r%   r0   r   r   r#   r$   strftimer3   r   rh   rr   r(   r   r/   r4   )rv   rH   rT   rM   dashboard_fromdashboard_torV   yesterday_str	week_fromrk   r   q_fromq_toq_labelr6   overviewagent_countsleaderboardr   r   concernssentiment_rowsr   r   r   recentr   r   r   )rv   r}   rI   r   r   r   r   build_dashboard_panel_data   s  




  r   c                 C   s@   |pi }| ddkr| drt| t|d S t| ||dS )Nr   r   r   rT   )rE   r   r_   r   )rv   rH   rT   rR   r   r   r   build_panel_datau  s   r   c              
   C   sf   t |pi }zt| ||d}||d< ||d< W |S  ty2 } ztd| | W Y d }~|S d }~ww )Nr   
panel_datalive_analyticsz'attach_live_analytics failed bid=%s: %s)r2   r   rm   rn   ro   )rv   rH   rT   rR   panelrq   r   r   r   attach_live_analytics  s   
r   )NN)%__doc__loggingrb   r   r   r   r   decimalr   typingr   r   r	   r
   r   r   	getLogger__name__rn   r$   r   r    r%   r(   r_   rG   rS   rh   rr   boolrD   r   r   r   r   r   r   r   r   r   r   <module>   s     
&",*
	
*
!

 A


