
    bi*                         d dl Zd dlZd dlmZmZ d dlmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ  ee          Z G d d          ZdS )	    N)date	timedelta)DictAnyListOptional)HealthDataQuery)ManualLogStorage)setup_loggerc                       e Zd ZdZd Zddedej        fdZddede	e
ef         fdZddede	e
ef         fd	Zddede	e
ef         fd
Zdde
de
dede	e
ef         fdZdde
de
dedede	e
ef         f
dZdS )HealthAnalystz}
    Advanced analytics engine for health data using Pandas.
    Calculates correlations, trends, and lifestyle impacts.
    c                 R    t                      | _        t                      | _        d S )N)r	   queryr
   manual_storage)selfs    0/root/projects/butler/health/analytics/engine.py__init__zHealthAnalyst.__init__   s#    $&&
.00       daysreturnc                 d   t          j                    }|t          |          z
  }g d}i }|}||k    rDd|                                i||                                <   |t          d          z  }||k    D|D ]}| j                            |||          }|D ]}	t          j        }
t          |	d          r|	j	        }
nct          |	t                    rNd|	v r	|	d         }
nAd|	v r	|	d         }
n4d|	v r	|	d         }
n'd	|	v r	|	d	         }
nd
|	v r|	                    d
d          }
|	                    d          p|	                    d          }|r||v r|
||         |<   Ō| j                            ||          }|D ]}|j        }||v rxt!          d |j        D                       ||         d<   |j        rdnd||         d<   |j        pd||         d<   t'          d |j        D                       rdnd||         d<   | j                            d||          }|D ]}	t          |	t                    s|	                    d          }|r||vr5||         }|	                    d          rdnd|d<   |	                    dd          |	                    dd          z   |	                    dd          z   |	                    dd          z   |d<   |	                    d          rdnd|d<   |	                    dd          |d<   |	                    d           rdnd|d!<   |	                    d"          rdnd|d#<   |	                    d$          rdnd|d%<   |	                    d&          rdnd|d'<   |	                    d(          rdnd|d)<   |	                    d*          rdnd|d+<   t+          j        t/          |                                                    }t+          j        |d                   |d<   |                    d                              d          }|S ),z
        Fetch all relevant data for the last N days and merge into a single DataFrame.
        Includes Garmin metrics, manual logs, and Garmin Lifestyle Logging data.
        )r   )sleep
heart_ratestressbody_batterystepshrvrhrr      valueaverage_heart_rateoverall_sleep_scoreresting_heart_rateaverage_stress_levelchargedr   calendar_datec                     g | ]}d S )r     ).0_s     r   
<listcomp>z/HealthAnalyst.get_dataframe.<locals>.<listcomp>:   s    7W7W7Wa7W7W7Wr   alcohol_unitshas_alcoholNormalfasting_modec              3   L   K   | ]}d |j                                         v V   dS )	magnesiumN)supplement_namelower)r*   ss     r   	<genexpr>z.HealthAnalyst.get_dataframe.<locals>.<genexpr>=   sO        <F  <FijK1K\KbKbKdKd<d  <F  <F  <F  <F  <F  <Fr   has_magnesiumlifestyle_loggingalcohol_logged
gl_alcoholalcohol_beeralcohol_winealcohol_spiritalcohol_othergl_alcohol_totalmorning_caffeine_loggedgl_morning_caffeinemorning_caffeine_coffeegl_morning_coffeelate_caffeine_loggedgl_late_caffeinehealthy_mealsgl_healthy_mealsheavy_mealsgl_heavy_meals
late_mealsgl_late_mealslight_exercisegl_light_exerciseintermittent_fasting
gl_fasting)r   todayr   	isoformatr   get_metric_rangenpnanhasattrr!   
isinstancedictgetr   get_logs_in_rangelog_datesumalcohol_entriesr0   anysupplement_entriespd	DataFramelistvaluesto_datetimesort_values	set_index)r   r   end_date
start_datemetrics_to_fetchdata_mapcurrmetricpointspvald_strlogsloglifestyle_pointsrowdfs                    r   get_dataframezHealthAnalyst.get_dataframe   s   
 :<<	t 4 4 44
ccch*0$..2B2B)CHT^^%%&I1%%%%D h ' 	2 	2FZ00XNNF 2 2f1g&& Cag4(( C+q00:N8O##.!331=R;SSS-22!<P:QCC/144A>T<Ucc"aquuY/B/Bo..?!%%-- 2Uh...1HUOF+2 "44ZJJ 	M 	MCLE  367W7W3CV7W7W7W3X3X0696I1Pq.252B2Nh/8;  <F  <Fnq  oE  <F  <F  <F  9F  9F  4M11  LM0  :667JJX`aa! 	J 	JAa&& EE&MME E115/C%&UU+;%<%< C!Cna((155+C+CC&**+-.UU?A-F-FG "#
 /0ee4M.N.N)UTUC%&'(uu-F'J'JC#$+,551G+H+H&OaaaC"#+,55+A+A&HaaqC"#)*})=)=$DAA1C !()l(;(;#B11C ,-EE2B,C,C'JqqC#$%&UU+A%B%B IC\$x001122^BvJ//6
^^F##--f55	r   Z   c                    |                      |          }|j        rddiS |d                             d          |d<   |d                             d          |d<   |d                             d          |d	<   i }||d
         dk             }||d
         dk             }t          |          dk    rt          |          dk    rt          |          t          |          t	          |d                                                   t	          |d                                                   t	          |d                                                   t	          |d                                                   t	          |d                                         |d                                         z
            d|d<   |S )z`
        Analyze impact of Alcohol and Activity on Next-Day Recovery (Sleep, HRV, RHR).
        errorzNo data availabler   
next_sleepr   next_rhrr   next_hrvr.   r    r   )sample_size_alcoholsample_size_soberavg_sleep_alcoholavg_sleep_soberavg_rhr_alcoholavg_rhr_sober
sleep_diffalcohol_impact)ru   emptyshiftlenfloatmean)r   r   rt   resultsalcohol_days
sober_dayss         r   analyze_recovery_correlationsz+HealthAnalyst.analyze_recovery_correlations_   s    %%8 	2011 g;,,R00<E,,:E,,: "]+q01=)Q./
|q  S__q%8%8'*<'8'8%(__%*<+E+J+J+L+L%M%M#(L)A)F)F)H)H#I#I#(j)A)F)F)H)H#I#I!&z*'='B'B'D'D!E!E#L$>$C$C$E$E
S_H`HeHeHgHg$ghh) )G$% r   c                    |                      |          }|j        rddiS |d                             d                                          |d<   |d                             d                                          |d<   |                    dg          }t          |          d	k    rt          j        |j        d
         d                   s|j        d
         d         n|j        d
         d         }t          j        |j        d         d                   s|j        d         d         n|j        d         d         }|t          |          t          |          ||k     rdnddS ddiS )z1
        Analyze RHR vs Activity trends.
        rx   No datar      rhr_rollr   
steps_rollsubset
   r   ry   	improving	declining)period_daysstart_rhr_7d_avgend_rhr_7d_avgtrendmsgz"Not enough data for trend analysis)
ru   r   rollingr   dropnar   rS   isnanilocr   )r   r   rt   valid	start_rhrend_rhrs         r   analyze_fitness_trendsz$HealthAnalyst.analyze_fitness_trends   si    %%80Wi00 E**1--2244:g;..q116688< 		%	))u::?? :<%*Q-PZB[9\9\v
1j11bgblmnbopubvI8:BPZA[8\8\wejnZ00bgblmobpqvbwG  $$))$4$4"'..(/)(;(;	   ;<<r   c                     |                      |          }|j        rddiS i }|                    d          d                                                                         }||d<   |S )z2
        Analyze Fasting and Supplements.
        rx   r   r0   r   fasting_sleep_scores)ru   r   groupbyr   to_dict)r   r   rt   r   fasting_statss        r   analyze_lifestyle_impactz&HealthAnalyst.analyze_lifestyle_impact   sn     %%80Wi00 

>227;@@BBJJLL*7&'r   condition_col
target_colc           	      L   |                      |          }|j        rddiS ||j        vs	||j        vr
dd| d| iS |||         dk             |         }|||         dk             |         }t          |          dk    st          |          dk    rddiS |                                }|                                }|dk    r||z
  |z  dz  nd}	||t          |          t          |          t          |          t          |          t          |	          ||k    rdnd	d
S )z
        Compare average of 'target_col' when 'condition_col' is non-zero vs zero.
        Example: Sleep Score when has_magnesium=1 vs 0.
        rx   r   Columns not found:  or r   z2One group has no data (e.g. never took supplement)d   betterworse)	conditiontargetavg_with_conditionavg_without_conditionsample_withsample_withoutdifference_pctverdict)ru   r   columnsr   r   r   )
r   r   r   r   rt   
group_truegroup_falseavg_true	avg_falsediff_pcts
             r   compare_groupszHealthAnalyst.compare_groups   sZ   
 %%80Wi00
**j
.J.JR=RRjRRSS=)A-.z:
M*a/0<z??a3{#3#3q#8#8QRR??$$$$&&	AJaX	)Y6#==UV ' "'//%*9%5%5z??!+..#Hoo#+i#7#7xxW	
 	
 		
r   r    driverr   lagc                    |                      |          }|j        rddiS ||j        vs	||j        vr
dd| d| iS d| }||                             |           ||<   |                    ||g          }t          |          dk     rddiS ||                             ||                   }|||t          j        |          st          |          nd	t          |          d
|dddS )a  
        Analyze if 'driver' on Day T correlates with 'target' on Day T+lag.
        Example: Alcohol (T) -> Sleep Score (T+1).
        
        Args:
            driver: Column name of the driver (e.g., 'alcohol_units', 'stress').
            target: Column name of the target (e.g., 'sleep', 'hrv', 'rhr').
            lag: Days to shift target (1 means next day).
            days: Lookback window.
        rx   r   r   r   target_lag_r      zNot enough data points (<5)g        z Correlation z.2fz4 (1.0 is perfect positive, -1.0 is perfect negative))r   r   lag_dayscorrelationsample_sizer   )
ru   r   r   r   r   r   corrr_   isnar   )	r   r   r   r   r   rt   r   r   r   s	            r   analyze_lagged_correlationz(HealthAnalyst.analyze_lagged_correlation   s-    %%80Wi00 ##vRZ'?'?G6GGvGGHH )3((
F))3$//: 		&*!5	66u::>>:;; V}!!%
"344 .0gdmmD5;;;u::a4aaaa
 
 	
r   N)r   )rv   )r    rv   )__name__
__module____qualname____doc__r   intr_   r`   ru   r   strr   r   r   r   r   r   r)   r   r   r   r      sx        
1 1 1H H# Hr| H H H HT( (# (tCH~ ( ( ( (T= =3 =S#X = = = =: S $sCx.     
 
C 
S 
 
UYZ]_bZbUc 
 
 
 
>&
 &
 &
c &
 &
WZ &
dhilnqiqdr &
 &
 &
 &
 &
 &
r   r   )pandasr_   numpyrS   datetimer   r   typingr   r   r   r   health.services.queryr	   "health.services.manual_log_storager
   health.utils.logging_configr   r   loggerr   r)   r   r   <module>r      s            $ $ $ $ $ $ $ $ , , , , , , , , , , , , 1 1 1 1 1 1 ? ? ? ? ? ? 4 4 4 4 4 4	h		p
 p
 p
 p
 p
 p
 p
 p
 p
 p
r   