a
    %ßiÅ%  ã                   @   sê   d Z ddlmZ ddlmZ ddlmZmZ ddlZddlZddl	Z	e
edœdd„Zeed	œd
d„Zeee d	œdd„Zeeedœdd„Zee
edœdd„Zeed	œdd„Zeeeddœdd„Zeeddœdd„Zeeeddœdd„ZdS )zy
Tutorial State Tracking System

Manages tutorial progress, onboarding completion, and tooltip tracking for new players.
é    )Údatetime)Úget_database_connection)ÚCallableÚOptionalN)Ú
tooltip_idÚreturnc                 C   s   t t d| ¡ƒS )z1Validate tooltip ID contains only safe charactersz^[a-zA-Z0-9_-]+$)ÚboolÚreÚmatch)r   © r   ú3/var/www/lichun.app/lichun/ws/retention/tutorial.pyÚvalidate_tooltip_id   s    r   )Ú	player_idr   c              
   C   s’  t | tƒr| dkrdddœS d}d}�zHz®tƒ }|jdd�}| d| f¡ | ¡ }|rŠd|d	 t|d
 ƒdœW W |r|| ¡  |rˆ| ¡  S | d| f¡ | ¡  t	 
d| › �¡ ddddœW W |rÊ| ¡  |rÖ| ¡  S  t�yN } z^|rô| ¡  t	jd| › d|› �dd� dt|ƒdœW  Y d}~W |�r6| ¡  |�rD| ¡  S d}~0 0 W |�r`| ¡  |�rŽ| ¡  n|�r~| ¡  |�rŒ| ¡  0 dS )z‡
    Initialize tutorial tracking for new player
    Returns: {'success': bool, 'tutorial_step': int, 'onboarding_complete': bool}
    r   Fú+Invalid player_id: must be positive integer©ÚsuccessÚerrorNT©Ú
dictionaryú;SELECT * FROM player_tutorial_progress WHERE player_id = %sÚtutorial_stepÚonboarding_complete)r   r   r   z¸INSERT INTO player_tutorial_progress
               (player_id, tutorial_step, onboarding_complete, first_session_date, tooltips_seen)
               VALUES (%s, 0, FALSE, NOW(), '{}')z Initialized tutorial for player z'Error initializing tutorial for player ú: ©Úexc_info)Ú
isinstanceÚintr   ÚcursorÚexecuteÚfetchoner   ÚcloseÚcommitÚloggingÚinfoÚ	ExceptionÚrollbackr   Ústr)r   Úconnr   ÚexistingÚer   r   r   Úinitialize_tutorial   sn    
þ
ýßüýðú
ýr*   c              
   C   sz  t | tƒr| dkr&t d| › �¡ dS d}d}�z&z¤tƒ }|jdd�}| d| f¡ | ¡ }|s€W W |rp| ¡  |r|| ¡  dS |d r–t	 
|d ¡ni }|d t|d	 ƒ|t|d
 ƒdœW W |rÊ| ¡  |rÖ| ¡  S  t�y6 } zFtjd| › d|› �dd� W Y d}~W |�r| ¡  |�r*| ¡  dS d}~0 0 W |�rH| ¡  |�rv| ¡  n|�rf| ¡  |�rt| ¡  0 dS )z(Get current tutorial progress for playerr   zInvalid player_id: NTr   r   Útooltips_seenr   r   Úskip_tutorial)r   r   r+   r,   z+Error getting tutorial progress for player r   r   )r   r   r"   r   r   r   r   r   r    ÚjsonÚloadsr   r$   )r   r'   r   Úresultr+   r)   r   r   r   Úget_tutorial_progressN   s^    þì

üñú
ýr0   )r   Únew_stepr   c              
   C   s„  t | tƒr| dkrdddœS t |tƒr6|dk s6|dkr@dddœS d}d}�zz|tƒ }| ¡ }| d|| f¡ | d	| t d
|i¡f¡ | ¡  t 	d| › d|› �¡ d|dœW W |r¼| 
¡  |rÈ| 
¡  S  t�y@ } z^|ræ| ¡  tjd| › d|› �dd� dt|ƒdœW  Y d}~W |�r(| 
¡  |�r6| 
¡  S d}~0 0 W |�rR| 
¡  |�r€| 
¡  n|�rp| 
¡  |�r~| 
¡  0 dS )z^
    Advance player to next tutorial step
    Returns: {'success': bool, 'new_step': int}
    r   Fr   r   éd   z*Invalid new_step: must be between 0 and 99NzKUPDATE player_tutorial_progress SET tutorial_step = %s WHERE player_id = %szŠINSERT INTO tutorial_milestones
               (player_id, milestone_type, milestone_data)
               VALUES (%s, 'step_complete', %s)ÚstepúPlayer z advanced to tutorial step T)r   r1   z(Error updating tutorial step for player r   r   )r   r   r   r   r   r-   Údumpsr!   r"   r#   r    r$   r%   r   r&   )r   r1   r'   r   r)   r   r   r   Úupdate_tutorial_stepy   sZ    

þüþñú
ýr6   )r   r   r   c              
   C   sÆ  t | tƒr| dkrdddœS t |tƒr.| ¡ s8dddœS t|ƒsPdd|› �dœS d}d}�zHz¬tƒ }| ¡ }| d|| f¡ |jdkr¬dd	dœW W |rž| 	¡  |rª| 	¡  S | d
| t
 d|i¡f¡ | ¡  t d| › d|› �¡ ddiW W |rú| 	¡  |�r| 	¡  S  t�y‚ } z`|�r(| ¡  tjd| › d|› �dd� dt|ƒdœW  Y d}~W |�rj| 	¡  |�rx| 	¡  S d}~0 0 W |�r”| 	¡  |�rÂ| 	¡  n|�r²| 	¡  |�rÀ| 	¡  0 dS )zI
    Mark a tooltip as seen by player
    Returns: {'success': bool}
    r   Fr   r   z,Invalid tooltip_id: must be non-empty stringzInvalid tooltip_id format: NzðUPDATE player_tutorial_progress
               SET tooltips_seen = JSON_SET(
                   COALESCE(tooltips_seen, '{}'),
                   CONCAT('$.', %s),
                   TRUE
               )
               WHERE player_id = %szPlayer tutorial not initializedz‰INSERT INTO tutorial_milestones
               (player_id, milestone_type, milestone_data)
               VALUES (%s, 'tooltip_seen', %s)r   r4   z saw tooltip: r   Tz!Error marking tooltip for player r   r   )r   r   r&   Ústripr   r   r   r   Úrowcountr    r-   r5   r!   r"   r#   r$   r%   r   )r   r   r'   r   r)   r   r   r   Úmark_tooltip_seen­   sh    

ø
æü
	ôú
ýr9   c              
   C   sZ  t | tƒr| dkrdddœS d}d}�zzvtƒ }| ¡ }| d| f¡ ddlm} || d||ƒ}| ¡  t 	d	| › d
�¡ dddœW W |r’| 
¡  |rž| 
¡  S  t�y } z^|r¼| ¡  tjd| › d|› �dd� dt|ƒdœW  Y d}~W |� rþ| 
¡  |�r| 
¡  S d}~0 0 W |�r(| 
¡  |�rV| 
¡  n|�rF| 
¡  |�rT| 
¡  0 dS )zr
    Mark onboarding as complete and award achievement
    Returns: {'success': bool, 'reward_diamonds': int}
    r   Fr   r   Nz”UPDATE player_tutorial_progress
               SET onboarding_complete = TRUE, onboarding_completed_date = NOW()
               WHERE player_id = %s)Úcheck_and_unlockÚfirst_stepsr4   z completed onboardingTé   )r   Úreward_diamondsz'Error completing onboarding for player r   r   )r   r   r   r   r   Zretention.achievementsr:   r!   r"   r#   r    r$   r%   r   r&   )r   r'   r   r:   Zachievement_resultr)   r   r   r   Úcomplete_onboardingí   sR    
ü	þñú
ýr>   )r   Úmessage_dataÚsend_to_clientr   c                 C   s0   |  d¡}t| |ƒ}|d r,|| d|dœƒ dS )z/Handle tutorialStepComplete message from clientr3   r   ZtutorialStepUpdated)Útyper3   N)Úgetr6   )r   r?   r@   r3   r/   r   r   r   Úhandle_tutorial_step_complete!  s    

þrC   )r   r?   r   c                 C   s   |  d¡}t| |ƒ dS )z&Handle tooltipSeen message from clientZ	tooltipIdN)rB   r9   )r   r?   r   r   r   r   Úhandle_tooltip_seen,  s    
rD   c                 C   s(   t | ƒ}|d r$|| d|d dœƒ dS )z-Handle completeOnboarding message from clientr   ZonboardingCompleter=   )rA   ÚrewardN)r>   )r   r?   r@   r/   r   r   r   Úhandle_complete_onboarding1  s    þrF   )Ú__doc__r   Ú	functionsr   Útypingr   r   r-   r"   r	   r&   r   r   r   Údictr*   r0   r6   r9   r>   rC   rD   rF   r   r   r   r   Ú<module>   s   ;+4@4