o
    Ch@                     @   sv   d Z 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mZ ddlmZ ddlmZmZmZmZ G dd	 d	ZdS )
z
Data Manager for the MAB Recommendation System.
Manages data needed by recommender, client, and helps setup users in the engine.
    N)datetime	timedelta)ListDictAnyOptionalTuple   )DataController)
FeedbackDBProductCatalogUserDemographicsSearchHistoryc                	   @   s  e Zd ZdZd1defddZd2deded	efd
dZded	ee	ee
f  fddZdedefddZded	e	ee
f fddZdede	ee
f fddZded	ee	ee
f  fddZd3deded	e	ee
f fddZd4deded	ejfddZded	e	ee
f 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fd%d&Zd!ee	ee
f  d	efd'd(Zdeded	ee	ee
f  fd)d*Zd5ded,ed	e
fd-d.Zd	e	ee
f fd/d0ZdS )6DataManagerzEManages data operations and user setup for the recommendation engine.recommender_system.dbdb_pathc                 C   s   t || _i | _i | _d S N)r
   data_controlleruser_sessionsuser_states)selfr    r   P/Users/divyeshpatel/Desktop/sahana/Recommender/recommender_rl/db/data_manager.py__init__   s   

zDataManager.__init__Nuser_id
session_idreturnc                 C   sR   |du rt t  }|| jvrg | j|< |t g dd}| j| | |S )z4Create a new user session for tracking interactions.Nactive)r   
start_timeinteractionscurrent_state)intr   now	timestampr   append)r   r   r   Zsession_datar   r   r   create_user_session   s   

zDataManager.create_user_sessionc                 C   s@   || j v r| j | rt| j | D ]}|d dkr|  S qdS )z,Get the currently active session for a user.r    r   N)r   reversed)r   r   sessionr   r   r   get_active_session*   s   zDataManager.get_active_sessionc                 C   sH   || j v r | j | D ]}|d |krd|d< t |d<  dS q
dS dS )zEnd a user session.r   Zendedr    end_timeN)r   r   r"   )r   r   r   r'   r   r   r   end_user_session2   s   
zDataManager.end_user_sessionc                 C   s   zB| j |}|s| |}| j |}| j j|dd}||||| || ||d|d| || 	|d
}|| j
|< |W S  ty] } ztd|  i W  Y d}~S d}~ww )z.Setup user state in the recommendation engine.2   limituser_cluster_idlast_active)
r   Zdemographicsbehavior_summaryrecent_interactionscurrent_sessionpreferences
cluster_idr/   engagement_levelexploration_scoreu%   ❌ Error setting up user in engine: N)r   get_user_create_default_userget_user_behavior_summaryget_user_feedbackr(   _extract_user_preferencesget_calculate_engagement_level_calculate_exploration_scorer   	Exceptionprint)r   r   	user_infor0   Zrecent_feedback
user_stateer   r   r   setup_user_in_engine=   s0   

z DataManager.setup_user_in_enginenew_interactionc                 C   s   || j v rK| j | }|d d| t|d dkr$|d dd |d< | |d |d< | j|}| ||d< | |d |d< t	 |d< dS dS )	z'Update user state with new interaction.r1   r   d   Nr3   r5   r6   r/   )
r   insertlenr;   r   r9   r=   r>   r   r"   )r   r   rE   rB   r0   r   r   r   update_user_statea   s   

zDataManager.update_user_statec                 C   s   || j v r
| j | S | |S )z)Get current user state for the RL engine.)r   rD   )r   r   r   r   r   get_user_statex   s   


zDataManager.get_user_state
   
n_productsc                 C   s   zK|  |}|si W S | ||}||d|di |dd|dd|di |dg d	d
 |t jt  t  dkdd	}|W S  tyf } ztd|  i W  Y d	}~S d	}~ww )z3Get context data needed for making recommendations.r4   r3   r5   lowr6         ?r2   r1   NrK      )hourday_of_week
is_weekend)	r   user_clusterr3   r5   r6   Zsession_contextr1   available_productsZtime_contextu*   ❌ Error getting recommendation context: )	rJ    _get_available_products_for_userr<   r   r"   rP   weekdayr?   r@   )r   r   rL   rB   rT   contextrC   r   r   r   get_recommendation_context   s0   





z&DataManager.get_recommendation_context  r-   c              
   C   s*  zw| j j||d}|st W S t|}t|d |d< |d jj|d< |d jj|d< |d ddg|d< | 	|}|rO|
d	|d
< |
dd|d< tj|d dg dd|d< |d}tt||d< |d  j |d< |W S  ty } ztd|  t W  Y d}~S d}~ww )z.Get training data formatted for RL algorithms.r,   r'   r#   rP   rQ   rO      rR   r4   rS   r5   rM   price)Zvery_lowrM   mediumhighZ	very_high)binslabelsZprice_rangeZinteraction_sequenceZtime_since_lastu(   ❌ Error getting training data for RL: N)r   r:   pd	DataFrameto_datetimedtrP   	dayofweekisinrJ   r<   cutsort_valuesrangerH   difftotal_secondsr?   r@   )r   r   r-   feedback_datadfrB   rC   r   r   r   get_training_data_for_rl   s.   



z$DataManager.get_training_data_for_rlc                 C   s<   t |d| dddd}| j|}|dkr| j|S i S )zCreate a default user profile.ZUser_N)r   namegenderager.   r   )r   r   add_userr7   )r   r   Zdefault_userr   r   r   r8      s   z DataManager._create_default_userr   c           
      C   s  |si S i i t ddddi i d}g }|D ]}|d}|r-|d |dd |d |< |d}|rB|d	 |dd |d	 |< |d
}|rl|dkrl|| t|d d ||d d< t|d d ||d d< |d}|r|d |dd |d |< |d}	|	r|d |	dd |d |	< q|rt|t| |d d< tt|d 	 dd dddd |d< tt|d	 	 dd dddd |d	< |S )z2Extract user preferences from interaction history.infr   )minmaxavg)favorite_categoriesfavorite_brandsprice_preferenceevent_preferencesproduct_affinitycategoryrv   r	   
brand_namerw   r[   rx   rs   rt   
event_typery   
product_idrz   ru   c                 S      | d S Nr	   r   xr   r   r   <lambda>      z7DataManager._extract_user_preferences.<locals>.<lambda>TkeyreverseNrO   c                 S   r   r   r   r   r   r   r   r     r   )
floatr<   r$   rs   rt   sumrH   dictsorteditems)
r   r   r3   Zpricesinteractionr{   brandr[   r}   r~   r   r   r   r;      sV   









z%DataManager._extract_user_preferencesr0   c                 C   s(   | dd}|dkrdS |dkrdS dS )z Calculate user engagement level.recent_activityr      r]   rK   r\   rM   r<   )r   r0   r   r   r   r   r=     s   z'DataManager._calculate_engagement_levelc                 C   st   |sdS t tdd |D }t tdd |D }t |}|dkr$dS || }|| }|| d }tdtd|S )	z'Calculate user exploration score (0-1).rN   c                 s   $    | ]}| d r| d V  qdS )r{   Nr   .0r   r   r   r   	<genexpr>&     " z;DataManager._calculate_exploration_score.<locals>.<genexpr>c                 s   r   )r|   Nr   r   r   r   r   r   '  r   r      g      ?g        )rH   setrs   rt   )r   r   Zunique_categoriesZunique_brandsZtotal_interactionsZcategory_diversityZbrand_diversityr6   r   r   r   r>      s   z(DataManager._calculate_exploration_scorec              
   C   s\  z|  |}|di }| jjdd}|sg W S g }|D ]a}d}|d}	|	|di v r7||d |	 d 7 }|d}
|
|d	i v rN||d	 |
 d
 7 }|dd}|di }|dddkrvt||d  |d  }|d
k rv|d
7 }|||f q|jdd dd dd |d| D W S  ty } ztd|  g W  Y d}~S d}~ww )z9Get available products for recommendation (arms for MAB).r3   rY   r,   r   r{   rv   g333333?r|   rw   g?r[   rx   ru   c                 S   r   r   r   r   r   r   r   r   \  r   z>DataManager._get_available_products_for_user.<locals>.<lambda>Tr   c                 S   s   g | ]\}}|qS r   r   )r   productscorer   r   r   
<listcomp>]  s    z@DataManager._get_available_products_for_user.<locals>.<listcomp>Nu&   ❌ Error getting available products: )	rJ   r<   r   get_all_productsabsr$   sortr?   r@   )r   r   rL   rB   r3   Zall_productsZscored_productsr   r   r{   r   r[   Z
price_prefZ
price_diffrC   r   r   r   rU   5  s:   


z,DataManager._get_available_products_for_userjsonformatc              
   C   s   z(|  |}|sW dS | dkr|W S | dkr&| |}|jddW S |W S  tyB } ztd|  W Y d}~dS d}~ww )z%Export user data in specified format.Nr   csvF)indexu   ❌ Error exporting user data: )rJ   lowerrm   to_csvr?   r@   )r   r   r   rB   rl   rC   r   r   r   export_user_datae  s   

zDataManager.export_user_datac              
   C   sl   zt | jt dd | j D t | j ddW S  ty5 } ztd|  i W  Y d}~S d}~ww )zGet overall system statistics.c                 S   s"   g | ]}t d d |D r|qS )c                 s   s    | ]	}|d  dkV  qdS )r    r   Nr   r   sr   r   r   r     s    z?DataManager.get_system_statistics.<locals>.<listcomp>.<genexpr>)anyr   r   r   r   r     s   " z5DataManager.get_system_statistics.<locals>.<listcomp>Zoperational)Ztotal_usersZactive_sessionsZtotal_productsZsystem_statusu%   ❌ Error getting system statistics: N)rH   r   r   valuesr   r   r?   r@   )r   rC   r   r   r   get_system_statisticsy  s   z!DataManager.get_system_statistics)r   r   )rK   )rY   )r   )__name__
__module____qualname____doc__strr   r!   r%   r   r   r   r(   r*   rD   rI   rJ   rX   r`   ra   rm   r8   r   r;   r=   r   r>   rU   r   r   r   r   r   r   r      s$    $ 
!(&;"0r   )r   pandasr`   numpynpr   r   typingr   r   r   r   r   r   r
   modelsr   r   r   r   r   r   r   r   r   <module>   s    