U
    [Mhh%                     @   sb   d Z ddl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mZ ddlZG dd dZdS )	zM
Daily Hours Calculator - Calculate day-wise working hours with color coding
    )datetime	timedeltatimezone)DictListOptional)Session)funcand_Nc                   @   sh   e Zd Zdd ZeedddZeee	e	e
e dddZe
e ed	d
dZeee	e	edddZdS )DailyHoursCalculatorc                 C   s(   dddd| _ dddddddd	| _d S )
Ng      @g       @)lowmediumhighg      ?gffffff?g333333?g?        )ZdevelopmentZdatabaseZproductivityZbrowsersystemotherZentertainment)
thresholdsproductive_categories)self r   ./daily_hours_calculator.py__init__   s    zDailyHoursCalculator.__init__)hoursreturnc                 C   sP   || j d k rddddddS || j d k r<ddd	d
ddS ddddddS dS )z3Get status color and message based on working hoursr   z#ef4444z#fef2f2zBelow targetu   🔴)statuscolor
backgroundmessageiconr   z#f59e0bz#fffbebzOn tracku   🟡r   z#22c55ez#f0fdf4z
Excellent!u   🟢N)r   )r   r   r   r   r   get_status_info   s(    	z$DailyHoursCalculator.get_status_info)dbuser_id
start_dateend_dater   c                 C   s  |j ddddd}|j ddddd}|tjttjj|ktjj|ktjj|ktjj	 
 }i }|D ]}|j }||kr|ddi dd||< || d  |j7  < || d	  d
7  < | j|jd}	|j|	 }
|| d  |
7  < |j}||| d kr$dddd|| d |< || d | d  |j7  < || d | d  |
7  < || d | d  d
7  < qpg }| }| }||kr||kr2|| }|d d }|d d }| |}|t|dt|dt|dkr|| d ndd
|d |d |d |d |d d || n<| d}||dddddi d|d |d |d ddd |td
d7 }q|S )z6Calculate working hours for each day in the date ranger   )ZhourZminutesecondZmicrosecond   ;   i?B r   )date
total_timeworking_time
categoriesactivities_countr(   r+      g?r)   r*   )timer)   countr-   r.   i     d   r   r   r   r   r   )working_hourstotal_hoursproductivity_percentager   status_colorstatus_backgroundstatus_messagestatus_iconzNo activityu   ⚪)r'   r(   r)   r1   r2   r3   r*   r+   r   r4   r5   r6   r7   )Zdays)replaceZquerymodelsZActivityRecordfilterr
   r!   Z	timestampZorder_byZascallr'   Zdurationr   getcategoryr   updateroundappendr   )r   r    r!   r"   r#   Z
activities
daily_dataZactivityZactivity_dateZcategory_weightZworking_durationr=   resultZcurrent_dateZend_date_onlyZday_datar1   r2   Zstatus_infor   r   r   calculate_daily_hours:   s    



	


	




z*DailyHoursCalculator.calculate_daily_hours)rA   r   c           	      C   s  |sdddddddddd	S t dd |D }tdd |D }td	d |D }td
d |D }tdd |D }|rt|dd dnd}tdd |D dd dd}t|||rt|t| dndt|d||||r|d d|d dnd|r|d d|d dndd	S )z(Calculate weekly summary from daily datar   r   N)	Z
total_daysworking_daysZavg_working_hourstotal_working_hoursdays_above_targetdays_on_trackdays_below_targetbest_day	worst_dayc                 s   s   | ]}|d  V  qdS )r1   Nr   .0dayr   r   r   	<genexpr>   s     z:DailyHoursCalculator.get_weekly_summary.<locals>.<genexpr>c                 S   s   g | ]}|d  dkr|qS r1   r   r   rK   r   r   r   
<listcomp>   s      z;DailyHoursCalculator.get_weekly_summary.<locals>.<listcomp>c                 S   s   g | ]}|d  dkr|qS )r   r   r   rK   r   r   r   rP      s      c                 S   s   g | ]}|d  dkr|qS )r   r   r   rK   r   r   r   rP      s      c                 S   s   g | ]}|d  dkr|qS )r   r   r   rK   r   r   r   rP      s      c                 S   s   | d S Nr1   r   xr   r   r   <lambda>       z9DailyHoursCalculator.get_weekly_summary.<locals>.<lambda>)keyc                 S   s   g | ]}|d  dkr|qS rO   r   rK   r   r   r   rP      s      c                 S   s   | d S rQ   r   rR   r   r   r   rT      rU   )rV   defaultr/   r'   %Y-%m-%dr1   )r'   r   )sumlenmaxminr?   strftime)	r   rA   rE   rD   rF   rG   rH   rI   rJ   r   r   r   get_weekly_summary   sR     z'DailyHoursCalculator.get_weekly_summaryc                 C   sX   |  ||||}| |}|D ]}|d d|d< q||| j|d|dddS )z$Generate complete daily hours reportr'   rX   )startend)rA   Zsummaryr   Z
date_range)rC   r^   r]   r   )r   r    r!   r"   r#   rA   Zweekly_summaryrM   r   r   r   calculate_daily_report   s    
z+DailyHoursCalculator.calculate_daily_reportN)__name__
__module____qualname__r   floatr   r   r   intr   r   rC   r^   ra   r   r   r   r   r      s     g-  r   )__doc__r   r   r   typingr   r   r   Zsqlalchemy.ormr   Z
sqlalchemyr	   r
   r9   r   r   r   r   r   <module>   s   