U
    [Mh>                     @   s^   d Z ddlmZ ddlmZmZ ddlZddlmZ ddlm	Z	 ddl
mZ G dd	 d	ZdS )
zP
Productivity Calculator - Analyze user productivity based on activity patterns
    )datetime)DictListN)ActivityWatchClient)and_)Sessionc                   @   s   e Zd Zdd ZeedddZeedddZe	e
j e	e d	d
dZeedddZeeedddZdeeeeedddZeee	ee	e dddZe	e
j ed	ddZe	e
j ed	ddZdS )ProductivityCalculatorc                 C   s:   dddddddd| _ dd	d
dd| _ddddd| _d S )N      ?gffffff?皙?g        g?g333333?)developmentZproductivityZdatabasebrowserentertainmentsystemotherg333333?g?gffffff?g      ?)
peak_hourseveningnight
late_nightg?g?g      ?)short_focusmedium_focus
long_focus
deep_focus)category_weightstime_multipliersfocus_bonusesself r   ./productivity_calculator.py__init__   s$    	zProductivityCalculator.__init__)hoursreturnc                 C   s`   |dkrdS t |d }|d }|d }|dkr:| dS |dkrL| dS | d| dS dS )z@Convert decimal hours to readable format (e.g., 5.5 -> '5h 30m')r   0h<   mhzh N)int)r   r    Ztotal_minutesZ
hours_partZminutes_partr   r   r   format_time_readable+   s    

z+ProductivityCalculator.format_time_readable)	timestampr!   c                 C   sb   |j }d|  krdk r"n ndS d|  kr6dk r>n ndS d|  krRdk rZn ndS dS d	S )
z0Categorize time of day for productivity analysis	      r      r      r   r   N)hour)r   r(   r-   r   r   r   get_time_category;   s    z(ProductivityCalculator.get_time_category)
activitiesr!   c           	      C   s  |sg S g }|d j |d j|d j|d j|d gd}tdt|D ]}|| }||d  }t|j|j  }|j |d k}|dkr|r|j|d< |d  |j7  < |d | qH|d d	kr||  |j |j|j|j|gd}qH|d d	kr|| |S )
z:Identify focus sessions (continuous work on same category)r   )categoryZ
start_timeend_timedurationr/      r0   i,  r1   r2   r/   i  )	r0   r(   r2   rangelenabsZtotal_secondsappendcopy)	r   r/   focus_sessionsZcurrent_sessioniactivityZprev_activityZtime_gapZsame_categoryr   r   r   calculate_focus_sessionsH   s:    
	
z/ProductivityCalculator.calculate_focus_sessions)duration_secondsr!   c                 C   sX   |d }|dkr| j d S |dkr,| j d S |dkr>| j d S |dkrP| j d S d	S d
S )z4Get focus bonus multiplier based on session durationr#      r   x   r   r      r   r	   N)r   )r   r=   Zduration_minutesr   r   r   get_focus_bonusv   s    



z&ProductivityCalculator.get_focus_bonus)
start_dateend_dater!   c           	      C   s   t  }z|||}W nV tk
rl } z8td|  ddddddi ddddddgd W Y S d}~X Y nX |sddddddi ddddddgdS g }|D ]6}tdd	|d
 |d |d |d d }|| q| dd|||S )z=Calculate productivity score directly from ActivityWatch dataz#Error fetching ActivityWatch data: r   r"   z"Error fetching ActivityWatch data.)overall_score
total_timeproductive_timetotal_time_formattedproductive_time_formattedproductivity_percentagecategory_breakdownr9   longest_focus_sessionlongest_focus_session_formattedaverage_focus_sessionaverage_focus_session_formattedrecommendationsN+No activity data available for this period.ZMockActivityr   r0   r2   application_namer(   )r0   r2   rQ   r(   )r   Zget_activity_data	Exceptionprinttyper7   calculate_productivity_score)	r   rB   rC   Z	aw_clientZactivity_dataeZmock_activitiesr;   Zmock_activityr   r   r   /calculate_productivity_score_from_activitywatch   sX    
zFProductivityCalculator.calculate_productivity_score_from_activitywatchN)dbuser_idrB   rC   r!   c                 C   s  |dkrL| tjttjj|ktjj|ktjj|ktjj 	 }|sfddddi g dgdS t
dd |D }d}i }i }	|D ]}
|
j}|
j}| j|d}| |
j}| j|d}|| | }||7 }||krd||< d|	|< ||  |7  < |	|  |7  < q| |}d}|D ]B}| |d	 }| j|d
 d}|d	 | |d  }||7 }q ||7 }|dkr|| d nd}td|}i }| D ]X\}}|	| ||	| dkr||	|  d nd|dkr|	| | d ndd||< q| ||||}t|d||| |d | |d t|d|t||rRtdd |D nd|rv| tdd |D d nd|rt
dd |D t| nd|r| t
dd |D t| d nd|| || |dS )z*Calculate comprehensive productivity scoreNr   rP   )rD   rE   rF   rI   rJ   r9   rO   c                 s   s   | ]}|j V  qd S Nr2   ).0r;   r   r   r   	<genexpr>   s     zFProductivityCalculator.calculate_productivity_score.<locals>.<genexpr>r
   r	   r2   r0   d   )
time_spentrF   Zproductivity_rateZpercentage_of_totalr3   i  c                 S   s   g | ]}|d  qS r[   r   r\   sr   r   r   
<listcomp>  s     zGProductivityCalculator.calculate_productivity_score.<locals>.<listcomp>c                 S   s   g | ]}|d  qS r[   r   r`   r   r   r   rb     s     r"   c                 S   s   g | ]}|d  qS r[   r   r`   r   r   r   rb     s     c                 S   s   g | ]}|d  qS r[   r   r`   r   r   r   rb      s     )rD   rE   rF   rG   rH   rI   rJ   r9   rK   rL   rM   rN   rO   Ztime_distributionZproductivity_trend)ZquerymodelsActivityRecordfilterr   rY   r(   Zorder_byZascallsumr0   r2   r   getr.   r   r<   rA   minitems_generate_recommendationsroundr'   r5   max_get_time_distribution_get_productivity_trend)r   rX   rY   rB   rC   r/   rE   rF   Zcategory_scoresZcategory_timesr;   r0   r2   Zbase_weightZtime_categoryZtime_multiplierZweighted_timer9   Zfocus_bonus_timeZsessionZfocus_bonusZ
bonus_timerI   rD   rJ   scorerO   r   r   r   rU      s    






    z3ProductivityCalculator.calculate_productivity_score)rp   
categoriesr9   rE   r!   c           	      C   s   g }|dk r| d n|dk r,| d n
| d |di dd}|d	i dd}||d
 krt| d ||d kr| d t|dk r| d nt|dkr| d |di dd}|dkr||d k r| d n
| d |S )z2Generate personalized productivity recommendationsr@   uI   🔴 Low productivity detected. Consider reducing distracting activities.r#   u9   🟡 Moderate productivity. There's room for improvement.u3   🟢 Good productivity! Keep up the excellent work.r   r_   r   r   g333333?uT   🌐 High browser usage detected. Consider using website blockers during work hours.r
   uI   🎮 Significant entertainment time. Try scheduling specific break times.   uO   🎯 Try to create longer focus sessions (30+ minutes) for better productivity.   uQ   ⚡ Many short sessions detected. Consider consolidating work into longer blocks.r   g?u?   💻 Consider dedicating more time to focused development work.uB   💻 Great development focus! You're spending quality time coding.)r7   rh   r5   )	r   rp   rq   r9   rE   rO   Zbrowser_timeZentertainment_timeZdev_timer   r   r   rk   (  s,    




z0ProductivityCalculator._generate_recommendationsc                 C   s<   i }|D ].}|j j}||kr$d||< ||  |j7  < q|S )z7Get time distribution across different hours of the dayr   )r(   r-   r2   )r   r/   Zhour_distributionr;   r-   r   r   r   rn   O  s    z-ProductivityCalculator._get_time_distributionc           
         s   |sdddS t |d }|d| }||d } fdd}||}||}|| }t|dk rhd}	n|dkrvd	}	nd
}	|	t|ddS )z&Calculate productivity trend over timeZstabler   )trendchangerr   Nc                    sH   | sdS t dd | D }t  fdd| D }|dkrD|| d S dS )Nr   c                 s   s   | ]}|j V  qd S rZ   r[   r\   ar   r   r   r]   i  s     zaProductivityCalculator._get_productivity_trend.<locals>.calc_half_productivity.<locals>.<genexpr>c                 3   s$   | ]}|j  j|jd  V  qdS )r
   N)r2   r   rh   r0   rv   r   r   r   r]   j  s   r^   )rg   )Zhalf_activitiesrE   rF   r   r   r   calc_half_productivitye  s    zNProductivityCalculator._get_productivity_trend.<locals>.calc_half_productivity   Z	improvingZ	decliningr3   )r5   r6   rl   )
r   r/   Z	mid_pointZ
first_halfZsecond_halfrx   Zfirst_productivityZsecond_productivityru   rt   r   r   r   ro   [  s    
z.ProductivityCalculator._get_productivity_trend)N)__name__
__module____qualname__r   floatstrr'   r   r.   r   rc   rd   r   r<   rA   rW   r   r&   rU   rk   rn   ro   r   r   r   r   r      s&   .7   m  'r   )__doc__r   typingr   r   rc   Zmy_activitywatch_clientr   Z
sqlalchemyr   Zsqlalchemy.ormr   r   r   r   r   r   <module>   s   