a
    'Ni	9                     @   s   d Z ddlZddlZddlmZmZmZ ddlmZ dd Z	dd Z
d	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )a  
Stats Manager Module

This module contains all stats and state update functions extracted from functions.py.
It manages player statistics, character updates, event checking, and various game state modifications.

Functions included:
- connect(player): Handle player reconnection and offline stats
- checkDilemmas(player): Check and trigger active dilemmas
- checkEvents(player, type): Check and trigger regular events
- checkDayEvents(player, type): Check and trigger day-specific events
- checkTutorialEvents(player, type): Check and trigger tutorial events
- scheduleComplete(person, scheduleID): Check if a schedule is complete
- updateAge(player): Update character ages and handle birthdays/deaths
- setLikesDislikes(person): Set random likes and dislikes for a character
- handleUpdates(updateObject, player, websocket): Handle incremental state updates
- parseOneTimeEvents(player): Parse and trigger one-time scheduled events
- handleMoods(player, person): Update character moods based on stats
- handleFinances(person): Handle character finances and savings
- getPeakEnergy(person): Calculate peak energy based on activities and habits

Note:
- FocusClass, getFocus(), getFocuses() are imported from education.education_manager
- updateDeathChance() is imported from health.health_manager
    N)
FocusClass
getFocusesgetFocus)updateDeathChancec                 C   s   d| _ | jj}|dkr||dk r(d}|}n"|dk r>d}|d }nd}|d }|dkrZ|d	7 }| jd
| d| d d| j_dS )zv
    Handle player reconnection and display offline time message.

    Args:
        player: playerClass instance
    	connectedr   <   minutei  hourday   szWelcome back, you missed  z of your life.N)
connectionofflineStatsminutesOfflinemessageQueueappend)playerminutesunittime r   4/var/www/lichun.app/lichun/ws/stats/stats_manager.pyconnect'   s    
r   c                 C   s`   | j D ]T}t d dk rddl}t|D ].}||jkr*t||}|| d|d    S q*qdS )z
    Check active dilemmas and trigger them randomly.

    Args:
        player: playerClass instance

    Returns:
        Event result if triggered, None otherwise
    d      r   Ndilemma)typer   )activeDilemmasrandomeventsdirfunctiongetattr)r   r   r    iitemr   r   r   checkDilemmasD   s    



r&   c                 C   sf   ddl }ddl}h d}t|D ]@}t||}t|r |j|vr ||s || |}|r |  S q dS )z
    Check and trigger regular events from events.py.

    Args:
        player: playerClass instance
        type (str): Event type to check for

    Returns:
        Event result if triggered, None otherwise
    r   N>   apply_tutorial_modifiersanswerOptiondilemmaClass	timeEventcheck_tutorial_triggersquestionEventZget_event_typeoneTimeEventZparse_event_dataConversationContextManagermessageEvent)r    inspectr!   r#   callable__name__iscoroutinefunction)r   r   r    r0   excluded_namesr$   r%   resultr   r   r   checkEventsX   s    


r6   c                 C   sf   ddl }ddl}h d}t|D ]@}t||}t|r |j|vr ||s || |}|r |  S q dS )z
    Check and trigger day-specific events from dayEvents.py.

    Args:
        player: playerClass instance
        type (str): Event type to check for

    Returns:
        Event result if triggered, None otherwise
    r   N>   r)   r*   r,   get_dailyPlanr-   r.   r/   )	dayEventsr0   r!   r#   r1   r2   r3   )r   r   r8   r0   r4   r$   r%   r5   r   r   r   checkDayEventsv   s    


r9   c              
   C   s   zHddl }|| sW dS || }|D ]}|| |}|r(|  W S q(W n4 ty| } ztd|  W Y d}~n
d}~0 0 dS )z
    Check and trigger tutorial events if player is in tutorial mode.

    Args:
        player: playerClass instance
        type (str): Event type to check for

    Returns:
        Event result if triggered, None otherwise
    r   Nz Error checking tutorial events: )tutorial_eventsis_tutorial_moder+   	Exceptionloggingerror)r   r   r:   ZtriggersZtrigger_funcr5   er   r   r   checkTutorialEvents   s    


&r@   c                 C   sH   t dt| jD ]2}|| j| jv r| j| j| j| jkr dS qdS )z
    Check if a schedule has been completed.

    Args:
        person: personClass instance
        scheduleID (str): ID of the schedule to check

    Returns:
        bool: True if schedule is complete, False otherwise
    r   TF)rangelen	schedulesid
executionsduration)personZ
scheduleIDr$   r   r   r   scheduleComplete   s    (rH   c                 C   s  ddl m} | jjd | j_| jjd dkr| jjd | j_t| jD ]\}}|jdkrH|jd | j| _| jjdkr|jd dkr| j|  j	d8  _	|jd dkr@| j|  jd7  _| j|  j	d8  _	t
|| j| _d	|jvr@t|d
dr@d|j d |j d |j d t|j d }|d|| d  S |j|j d t d ksj|jdkrd| j| _d|j d |j  d |j  d t|j d | _| j| j	dk rHd| j| _	qH| S )z
    Update character ages and handle birthdays, deaths, and relationship decay.

    Args:
        player: playerClass instance

    Returns:
        playerClass or messageEvent: Updated player or birthday message event
    r   )messageFunctionr      alive      im  	classmatetitleFzYour r   z is now z years old.birthdayTr   x   Zdeadz has died at the age of i)r    rI   cageHoursageDays	enumeraterstatusageYearsaffinityr   deathChancerelationshipsr#   rO   	firstnamelastnamestrhealthr   
capitalizemessage)r   rI   indexr%   ra   r   r   r   	updateAge   s,    

0*:rc   c                    sJ   g d}t |t dd _ fdd|D }t |t dd _ S )z
    Set random likes and dislikes for a character.

    Args:
        person: personClass instance

    Returns:
        personClass: Updated person with likes and dislikes
    )0ZsportsZmusicZartreadingwritingZsciencemathhistoryZpoliticsZ
philosophyZreligionZnatureZanimalstravelfoodZcookingZcarsZfashionZfitnessr_   Z
technologyzvideo gamesZmoviesZtvZtheaterZdanceZcomedyZdramaZhorrorromanceactionZ	adventureZfantasyzsci-fiZmysteryZthrillerZcrimeZdocumentaryZanimeZmangaZcartoonszboard gamesz
card gamesBroccoliCelery	MushroomszBrussels sproutsOnionsr      c                    s   g | ]}| j vr|qS r   )likes).0ZinterestrG   r   r   
<listcomp>       z$setLikesDislikes.<locals>.<listcomp>)r   samplerandintrq   dislikes)rG   Zpossible_interestsr   rs   r   setLikesDislikes   s
    
ry   c                 C   s\  g d}|D ]4}t |j|}|| |kr4|| |< q| |d qddg}|D ]>}t |j|}t|t| |g kr|| |< qN| |d qN|j| dkrt|j |j| d< n| dd |j| dkr| |j	|j|j
d n\|jdkr.|j	| d	kr.|jd
kr.| |j	|j|j
d ndD ]}| |d q2| rXd| d< | S dS )a  
    Handle incremental state updates to send to client.
    Only includes changed values to minimize data transfer.

    Args:
        updateObject (dict): Object to populate with updates
        player: playerClass instance
        websocket: WebSocket connection (not currently used)

    Returns:
        dict or False: Update object with type 'u' if changes exist, False otherwise
    )	energy
calcEnergy	happinessstressmoneyprestige
occupationintraDayMessagelocationNrC   	dailyPlan	gameSpeed	hourOfDay)dater   weekDayTextr   r   r   ur   F)r#   rR   getpoprB   r   printr   updater   r   )ZupdateObjectr   	websocket
attributes	attributeZplayer_valueZlist_attributeskeyr   r   r   handleUpdates   sD    



*
r   c                 C   s   t dt| jjD ]t}| jj| }|j| jkr| j|jkr| j|j	 | jj
| |jdkrt|drt||  d|_d|_d|_qdS )zf
    Parse and trigger one-time scheduled events.

    Args:
        player: playerClass instance
    r   Nrun_funcF)rA   rB   rR   oneTimeEventsr   r   r	   r   r   ra   r   completionFunchasattrr   completionArgscompletionKwargs)r   r$   eventr   r   r   parseOneTimeEvents;  s    


r   c                 C   s   |j dk r|j dkrd|_|j dkr*d|_|j dkr:d|_|j dkrT|jdkrTd|_|j dkrn|jdkrnd|_|j dkr|jdkr|jdkrd	|_d
S )z
    Update character mood based on energy and happiness levels.

    Args:
        player: playerClass instance (not currently used)
        person: personClass instance to update mood for
    (   
   Stressed	ExhaustedCalmr   	Fulfilled	DepressedHappyN)rz   moodr|   )r   rG   r   r   r   handleMoodsO  s    


r   c                 C   s   d}| j dkrd}n| j dkr"d}d}| jdkr| jD ]}|jdkr6||jj7 }q6t| dd	}|rt|d
d	dkrz|d9 }|  j|| 7  _d	S )zq
    Handle character finances including income and savings.

    Args:
        person: personClass instance
    g?frugalg?extravagantg?r   FjobNhourTypepartTimeg333333?)spendingHabitsr   activityRecordsr   levelsalaryr#   r~   )rG   ZsavingRatioincomerecordr   r   r   r   handleFinancesg  s    




r   c                 C   s   d}| j D ]}|jdkr
|d7 }q
| jD ]`}t|ddrB||j7 }| jD ]>}|j|jkrH|jdkrn||jj	7 }t
|j}|rH||j7 }qHq(|| _| j| j | _dS )z
    Calculate peak energy based on activities, habits, and focus settings.
    Updates person.peakEnergy and person.calcEnergy.

    Args:
        person: personClass instance
    r   quittingrp   energyModifierFr   N)habitsrW   
activitiesr#   r   r   rD   r   r   energy_modifierr   focus
peakEnergyrz   r{   )rG   r   habitactivityr   Z
foundFocusr   r   r   getPeakEnergy  s     	







r   )__doc__r   r=   education.education_managerr   r   r   health.health_managerr   r   r&   r6   r9   r@   rH   rc   ry   r   r   r   r   r   r   r   r   r   <module>   s"   $E