U
    %h>                     @   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?)developmentproductivity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   :/var/www/html/timesheet/backend/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durationr1      r2   i,  r3   r4   r1   i  )	r2   r*   r4   rangelenabstotal_secondsappendcopy)	r   r1   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_breakdownr<   longest_focus_sessionlongest_focus_session_formattedaverage_focus_sessionaverage_focus_session_formattedrecommendationsN+No activity data available for this period.ZMockActivityr   r2   r4   application_namer*   )r2   r4   rT   r*   )r   get_activity_data	Exceptionprinttyper:   calculate_productivity_score)	r   rE   rF   	aw_clientactivity_dataeZmock_activitiesr>   Zmock_activityr   r   r    /calculate_productivity_score_from_activitywatch   sX    
zFProductivityCalculator.calculate_productivity_score_from_activitywatchN)dbuser_idrE   rF   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   rS   )rG   rH   rI   rL   rM   r<   rR   c                 s   s   | ]}|j V  qd S Nr4   ).0r>   r   r   r    	<genexpr>   s     zFProductivityCalculator.calculate_productivity_score.<locals>.<genexpr>r
   r	   r4   r2   d   )
time_spentrI   Zproductivity_rateZpercentage_of_totalr5   i  c                 S   s   g | ]}|d  qS ra   r   rb   sr   r   r    
<listcomp>  s     zGProductivityCalculator.calculate_productivity_score.<locals>.<listcomp>c                 S   s   g | ]}|d  qS ra   r   rf   r   r   r    rh     s     r$   c                 S   s   g | ]}|d  qS ra   r   rf   r   r   r    rh     s     c                 S   s   g | ]}|d  qS ra   r   rf   r   r   r    rh      s     )rG   rH   rI   rJ   rK   rL   rM   r<   rN   rO   rP   rQ   rR   Ztime_distributionZproductivity_trend)querymodelsActivityRecordfilterr   r_   r*   order_byascallsumr2   r4   r   getr0   r   r?   rD   minitems_generate_recommendationsroundr)   r7   max_get_time_distribution_get_productivity_trend)r   r^   r_   rE   rF   r1   rH   rI   Zcategory_scoresZcategory_timesr>   r2   r4   Zbase_weightZtime_categoryZtime_multiplierZweighted_timer<   Zfocus_bonus_timesessionZfocus_bonusZ
bonus_timerL   rG   rM   scorerR   r   r   r    rY      s    






    z3ProductivityCalculator.calculate_productivity_score)rz   
categoriesr<   rH   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 recommendationsrC   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   re   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.)r:   rq   r7   )	r   rz   r{   r<   rH   rR   Zbrowser_timeZentertainment_timeZdev_timer   r   r    rt   (  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/   r4   )r   r1   Zhour_distributionr>   r/   r   r   r    rw   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changer|   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 r`   ra   rb   ar   r   r    rc   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)r4   r   rq   r2   r   r   r   r    rc   j  s   rd   )rp   )Zhalf_activitiesrH   rI   r   r   r    calc_half_productivitye  s    zNProductivityCalculator._get_productivity_trend.<locals>.calc_half_productivity   Z	improvingZ	decliningr5   )r7   r8   ru   )
r   r1   Z	mid_pointZ
first_halfZsecond_halfr   Zfirst_productivityZsecond_productivityr   r~   r   r   r    rx   [  s    
z.ProductivityCalculator._get_productivity_trend)N)__name__
__module____qualname__r!   floatstrr)   r   r0   r   rj   rk   r   r?   rD   r]   r   r(   rY   rt   rw   rx   r   r   r   r    r      s&   .7   m  'r   )__doc__r   typingr   r   rj   my_activitywatch_clientr   
sqlalchemyr   sqlalchemy.ormr   r   r   r   r   r    <module>   s   