o
    4h_                     @   s   d Z ddlZddlZddlZddlZddlZzddl	m
Z ddlmZ dZW n ey5   dZdZdZY nw ddlmZmZ ddlmZmZmZmZmZmZ dd	lmZmZ zdd
lmZmZ dZW n e yq   dZdZdZY nw G dd dej!Z"dS )z
Unified Multi-Armed Bandit Recommendation Environment.
Supports both CSV and database data sources with optional clustering integration.
    N)	RectangleTF)datetime	timedelta)DictAnyListOptionalTupleUnion   )RecommenderLoggerperformance_tracker)DataControllerDataManagerc                )   @   s  e Zd ZdZ												
								dWdeeeeef f dedededede	de	de	dedededededed ed!eee
f d"e
d#e
d$e
d%ef(d&d'Zdeeeeef f d(efd)d*Zdeeeeef f fd+d,Zd-efd.d/Zd0eeef fd1d2Zd3d4 ZdXdee d5eeeef  d(eejeeef f fd6d7Zd8eejee f d(eeje
e	e	eeef f fd9d:Zd8ee d(eeje
e	e	eeef f fd;d<Zd8ee d(eeje
e	e	eeef f fd=d>Zd(ejfd?d@Zd(ejfdAdBZd(ejfdCdDZd(eeeef  fdEdFZdGeeeef  d(eeeef  fdHdIZdGeeeef  d(eeeef  fdJdKZdLeeef d(ee
eeef f fdMdNZ dYdPefdQdRZ!dSdT Z"d(eeef fdUdVZ#dS )ZUnifiedRecommendationEnvz
    Unified Multi-Armed Bandit environment supporting both CSV and database data sources.
    Each 'arm' represents a product that can be recommended to users.
    2   d   r   NF
product_iduser_idbrandcategory_idcategory_code
event_type
event_time皙ɿ皙?333333?   data_sourcemax_arms	max_stepsn_suggestionsseeduse_clusteringuse_user_contextuse_price_optimizationproduct_coluser_col	brand_colcategory_colcategory_code_col	event_coltime_colbase_rewardsrepeat_penaltybrand_bonuscategory_bonusrelevance_windowc                 C   sl  t |tr	|dksJ dt |tr|dksJ d||ks"J d|du s/t |ts/J d|dur>t| tj| || _|| _|| _|oJt| _	|oOt| _
|oTt| _| || _td| j d | | | j	ss| j
ss| jrtstd	 d
| _	d
| _
d
| _n|   d| _d| _i | _i | _d| _d| _d| _g | _g | _g | _td| j dd| _td dS )a  
        Initialize the Unified Multi-Armed Bandit Recommendation Environment.

        Parameters:
        - data_source: Either a CSV file path (str) or database config (dict)
        - max_arms: Maximum number of arms (products) to consider
        - max_steps: Maximum number of steps in an episode
        - n_suggestions: Number of products to recommend simultaneously
        - seed: Random seed for reproducibility
        - use_clustering: Whether to use clustering insights (requires database)
        - use_user_context: Whether to use enhanced user context (requires database)
        - use_price_optimization: Whether to use price optimization (requires database)
        - product_col: Column name for product IDs (CSV only)
        - user_col: Column name for user IDs (CSV only)
        - brand_col: Column name for brand information (CSV only)
        - category_col: Column name for category IDs (CSV only)
        - category_code_col: Column name for category code information (CSV only)
        - event_col: Column name for event type information (CSV only)
        - time_col: Column name for event time information (CSV only)
        - base_rewards: Base rewards for each event type (CSV only)
        - repeat_penalty: Penalty for repeated products (CSV only)
        - brand_bonus: Bonus for same brand (CSV only)
        - category_bonus: Bonus for same category (CSV only)
        - relevance_window: Window for considering past interactions (CSV only)
        r   z$Max arms must be a positive integer.z)n_suggestions must be a positive integer.z%n_suggestions cannot exceed max_arms.NzSeed must be an integer.u/   🔧 Initializing Unified MAB Environment with z data source...uR   ⚠️  Enhanced features requested but not available. Falling back to basic mode.FZunified_recommendation_env_Zarms)nameu5   ✅ Unified MAB Environment initialized successfully!)
isinstanceintrandomr"   npr   r    r!   ENHANCED_FEATURES_AVAILABLEr#   r$   r%   _determine_data_source_typedata_source_typeprint_initialize_data_source_initialize_enhanced_featurescurrent_stepcurrent_user_idZuser_historyZproduct_historycurrent_sessionZrender_modefigepisode_rewardsepisode_actionsepisode_contextsr   logger)selfr   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1    rF   t/Users/divyeshpatel/Desktop/sahana/Recommender/recommender_rl/recommender/rl_recommender/UnifiedRecommendationEnv.py__init__*   sF   2




z!UnifiedRecommendationEnv.__init__returnc                 C   s2   t |tr|drdS dS t |trdS td)z"Determine the type of data source.z.csvcsvdatabasezCdata_source must be a CSV file path (str) or database config (dict))r3   strendswithdict
ValueErrorrE   r   rF   rF   rG   r8      s   


z4UnifiedRecommendationEnv._determine_data_source_typec                 C   s&   | j dkr| | dS | | dS )z)Initialize the data source based on type.rJ   N)r9   _initialize_csv_data_source _initialize_database_data_sourcerP   rF   rF   rG   r;      s   
z0UnifiedRecommendationEnv._initialize_data_sourcecsv_pathc                 C   st  t |ts	J dtj|sJ d| dt|| _t| dr'| j	du r/dddd	d
| _	| j| j
  | _| j| j  | _| j| j  | _| j| j  | _tj| jg| j | _tjtjjd| jdtjdtjjd| jdtjdtjjd| j| jftjdtjjd| j| jftjdtjjd| j| jftjdd| _td| jj d  d| j d| j d dS )zDInitialize CSV data source (legacy RecommendationEnv functionality).zCSV path must be a string.z	CSV file z does not exist.r-   N皙?Q?      ?      ࿩viewcartpurchaseremove_from_cartr   rF   lowhighshapedtype)r   session_stepsZprevious_brandsZprevious_categoriesZprevious_productsu   📊 Loaded CSV data: z interactions, z users, z	 products)!r3   rL   ospathisfilepdread_csvdatahasattrr-   r'   nuniqueZn_usersr&   
n_productsr(   Zn_brandsr)   Zn_categoriesgymspacesMultiDiscreter!   action_spacer   Boxr6   int32r    r1   observation_spacer:   r`   )rE   rS   rF   rF   rG   rQ      s,   
,z4UnifiedRecommendationEnv._initialize_csv_data_source	db_configc                 C   s   t std|dd}t|| _t|| _d| _tj	
| jg| j | _tj	tj	jdddtjdtj	jd| jdtjdtj	jd	d
dtjdtj	jd| j| jftjdd| _td|  dS )zJInitialize database data source (EnhancedRecommendationEnv functionality).z3Database features require db and clustering modulesdb_pathzrecommender_system.dbNr   i'  rF   r]   r   )
   )r   rb   user_contextavailable_productsu+   🗄️  Initialized database data source: )r7   ImportErrorgetr   data_controllerr   data_managerclustering_managerrl   rm   rn   r   r!   ro   r   rp   r6   rq   r    float32rr   r:   )rE   rs   rt   rF   rF   rG   rR      s   


z9UnifiedRecommendationEnv._initialize_database_data_sourcec              
   C   s   t sdS td | jrc| jrcz7| j }| j }| j }t|dkr=t|dkr=t|dkr=| j	||| td ntd d| _W n t
yb } ztd| d d| _W Y d}~nd}~ww td	 dS )
zLInitialize enhanced features (clustering, user context, price optimization).Nu&   🔧 Initializing enhanced features...r   u!   ✅ Clustering pipeline completedu>   ⚠️  Insufficient data for clustering, disabling clusteringFu*   ⚠️  Clustering initialization failed: z, disabling clusteringu!   ✅ Enhanced features initialized)r7   r:   r#   r}   r{   get_all_productsget_all_usersZget_all_feedbacklenZrun_full_clustering	Exception)rE   Zproducts_dataZ
users_datafeedback_dataerF   rF   rG   r<      s,   


$
z6UnifiedRecommendationEnv._initialize_enhanced_featuresoptionsc           	   
   C   s  |durt | tj | d| _g | _g | _g | _| jdur-tdur-t	| j d| _|r<|
ddur<|d | _n'| jdkrLt | j| j | _n| j }t|dkr`t |d | _nd| _| jdkrv| jrv| j| j}|| _nd| _|  }| j| j| j| j| j| jdd}| jdkr| jrz| j| j}||d	< W ||fS  ty } ztd
|  W Y d}~||fS d}~ww ||fS )z*Reset the environment to an initial state.Nr   r   rJ   r   rK   Z
clusteringrw   Zprice_optimization)r   
session_idr9   enhanced_features
user_stateu"   ⚠️  Could not get user state: )r5   r"   r6   r=   rA   rB   rC   r@   pltcloserz   r>   r9   choicerh   r'   r{   r   r   r$   r|   Zstart_user_sessionr?   _get_observationr#   r%   get_user_stater   r:   )	rE   r"   r   usersr   observationinfor   r   rF   rF   rG   reset  sT   



zUnifiedRecommendationEnv.resetactionc                 C   s   | j | jkr|  dddi fS t|dr| }n	t|ts"t|}dd |D }t|| jkr9t	d| j d| j
d	krC| |S | |S )
z-Execute one time step within the environment.        TFtolistc                 S   s   g | ]}t |qS rF   )r4   ).0arm_idxrF   rF   rG   
<listcomp>N  s    z1UnifiedRecommendationEnv.step.<locals>.<listcomp>zAction must contain exactly z arm selectionsrJ   )r=   r    r   ri   r   r3   listr   r!   rO   r9   	_step_csv_step_database)rE   r   rF   rF   rG   stepB  s   





zUnifiedRecommendationEnv.stepc           	      C   s   d}g }|D ]}|| j k r!tjdd}||7 }|||dd q|  jd7  _| j| | j| | j| jk}| 	 }||| jd}|||d|fS )z!Execute step for CSV data source.r   r   r   rY   )r   rewardr   )interactions_occurredtotal_rewardr   F)
rk   r6   r5   uniformappendr=   rA   rB   r    r   )	rE   r   r   r   r   r   doner   r   rF   rF   rG   r   Z  s,   
z"UnifiedRecommendationEnv._step_csvc                 C   s(  |   }t|| jk r|  dddddifS g }g }|D ]+}|t|k r:|| }| |\}}|| || q|d |ddd qt|}	|  jd	7  _| j|	 | j	| | j
ry| jry|D ]}|d
durx| j| j| qg| j| jk}
|  }||	| jt|d}||	|
d|fS )z&Execute step for database data source.g      TFerrorzNot enough products availableinvalidN)typer   r   r   )interactionsr   r   rx   )_get_available_productsr   r!   r   _simulate_user_interactionr   sumr=   rA   rB   r$   r|   rz   update_user_stater>   r    )rE   r   rx   Zrewardsr   Zproduct_idxproductr   interactionr   r   r   r   rF   rF   rG   r     sB   

z'UnifiedRecommendationEnv._step_databasec                 C   s   | j dkr	|  S |  S )z/Get the current observation of the environment.rJ   )r9   _get_observation_csv_get_observation_databaserE   rF   rF   rG   r     s   
z)UnifiedRecommendationEnv._get_observationc                 C      t | j| jdddgS )z$Get observation for CSV data source.r   r6   arrayr>   r=   r   rF   rF   rG   r        z-UnifiedRecommendationEnv._get_observation_csvc                 C   r   )z)Get observation for database data source.r   r   r   rF   rF   rG   r     r   z2UnifiedRecommendationEnv._get_observation_databasec              
   C   s   | j dkrttt| j| jS z!| jj| jd}| jr$| j	r$| 
|}| jr/| j	r/| |}|W S  tyL } ztd|  g W  Y d}~S d}~ww )z*Get available products for recommendation.rJ   )limitu*   ⚠️  Error getting available products: N)r9   r   rangeminrk   r   r{   r   r#   r}   _apply_clustering_filterr%   _apply_price_optimizationr   r:   rE   productsr   rF   rF   rG   r     s   


z0UnifiedRecommendationEnv._get_available_productsr   c              
   C   sb   z| j s|W S | j | j}|d| j W S  ty0 } ztd|  |W  Y d}~S d}~ww )z-Apply clustering-based filtering to products.Nu*   ⚠️  Error applying clustering filter: )r}   Zget_user_clusterr>   r   r   r:   )rE   r   user_clusterr   rF   rF   rG   r     s   z1UnifiedRecommendationEnv._apply_clustering_filterc              
   C   sT   z| j s|W S |d| j W S  ty) } ztd|  |W  Y d}~S d}~ww )z(Apply price-based filtering to products.Nu+   ⚠️  Error applying price optimization: )r}   r   r   r:   r   rF   rF   rG   r     s   z2UnifiedRecommendationEnv._apply_price_optimizationr   c                 C   sp   g d}t jj|g dd}ddddd}||d}|t jd	d7 }||d
| jt  |d}||fS )z)Simulate user interaction with a product.rX   )g333333?r   g333333?g?)prT   rU   rV   rW   r   r   r   )r   r   r   	timestampr   )	r6   r5   r   rz   normalr>   r   now	isoformat)rE   r   Zinteraction_typesZinteraction_typer-   r   r   rF   rF   rG   r     s   
z3UnifiedRecommendationEnv._simulate_user_interactionhumanmodec                 C   s\   |dkr%t d| j d| j  t d| j  t dt| jd dS |dkr,	 dS dS )	zRender the environment.r   zStep: /zUser: zTotal Reward: z.2fZ	rgb_arrayN)r:   r=   r    r>   r   rA   )rE   r   rF   rF   rG   render  s   zUnifiedRecommendationEnv.renderc                 C   s:   | j durt| j  d| _ t| dr| jr	 dS dS dS )z-Close the environment and clean up resources.Nr{   )r@   r   r   ri   r{   r   rF   rF   rG   r   $  s   
zUnifiedRecommendationEnv.closec              
   C   sR   | j | j| j| j| j| j| j| jdt| j	| j	rt
| j	ndt| jddS )z2Get information about the current algorithm state.r   r   )Ztotal_rewardsZ
avg_rewardZtotal_steps)r9   r   r!   r=   r>   r   Zepisode_stats)r9   r   r!   r=   r>   r#   r$   r%   r   rA   r6   meanr   rB   r   rF   rF   rG   get_algorithm_info/  s   z+UnifiedRecommendationEnv.get_algorithm_info)r   r   r   NFFFr   r   r   r   r   r   r   Nr   r   r   r   )NN)r   )$__name__
__module____qualname____doc__r
   rL   r   r   r4   boolfloatrH   r8   r;   rQ   rR   r<   r   r	   r6   ndarrayr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rF   rF   rF   rG   r   $   s    	

"k#:8>..'5***r   )#r   Z	gymnasiumrl   numpyr6   pandasrf   r5   rc   Zmatplotlib.pyplotZpyplotr   Zmatplotlib.patchesr   ZMATPLOTLIB_AVAILABLEr   r   r   typingr   r   r   r   r	   r
   rD   r   r   dbr   r   r7   ry   ZEnvr   rF   rF   rF   rG   <module>   s6     