a
    iZB  ã                   @   sH  d Z ddlmZmZmZ ddlmZmZ ddlZddl	Z	ddl
Z
ddlmZ dddd	d
œddddd
œddddd
œddddd
œddddd
œddddd
œddddd
œgZdd„ Zeeeef dœdd „Zeeeeef  d!œd"d#„Zeeeef dœd$d%„Zeeeef dœd&d'„Zed(œd)d*„Zeeeef dœd+d,„Zed-œd.d/„ZdS )0zŽ
Daily Login Reward System

Tracks 7-day login streaks and awards diamonds, energy, items, or prestige.
Streak resets if player misses a day.
é    )ÚDictÚAnyÚOptional)ÚdateÚ	timedeltaN)Úget_database_connectioné   Údiamondsé   z
5 Diamonds)ÚdayÚtypeÚamountÚnameé   é
   z10 Diamondsé   Úenergyé2   z	50 Energyé   é   z15 Diamondsé   z20 Diamonds + Itemé   é   z25 Diamondsé   z50 Diamonds Bonusc               
   Ã   s–   ddl m}  zLtD ],}| d|d |d |d |d fƒI dH  qt d	ttƒ› d
�¡ W n8 ty� } z tjd|› �dd� W Y d}~n
d}~0 0 dS )z“
    Insert reward definitions into database.
    Called during server startup.
    Uses async database pool for proper connection management.
    r   )Úexecute_querya@  INSERT INTO daily_login_rewards
                   (day_number, reward_type, reward_amount, display_name)
                   VALUES (%s, %s, %s, %s) AS new_reward
                   ON DUPLICATE KEY UPDATE
                   reward_amount=new_reward.reward_amount,
                   display_name=new_reward.display_namer   r   r   r   NzInitialized z daily login rewardsz"Error initializing daily rewards: T©Úexc_info)Údatabase_asyncr   ÚDAILY_REWARDSÚloggingÚinfoÚlenÚ	ExceptionÚerror)r   ÚrewardÚe© r&   ú8/var/www/lichun.app/lichun/ws/retention/daily_rewards.pyÚinitialize_daily_rewards   s    ù
r(   )Ú	player_idÚreturnc              
   C   s\  d}d}t  ¡ }�z&�z–tƒ }|jdd�}| d| f¡ | ¡ }|s | d| |f¡ | ¡  tdƒ}t 	d| › d�¡ dd|d	d
œW W |r’| 
¡  |rž| 
¡  S |d }||krÞd	|d dd	d
œW W |rÐ| 
¡  |rÜ| 
¡  S || j}d	}|dk�r|d d }	|d d d }
n$d}	d}
d}t 	d| › d|› d�¡ | d|	||
| f¡ | ¡  t|d ƒ}t 	d| › d|	› d|d › �¡ d|	||d
œW W |�rž| 
¡  |�r¬| 
¡  S  t�y } zRtjd| › d|› �dd� d	ddd	d
œW  Y d}~W |�r | 
¡  |�r| 
¡  S d}~0 0 W |�r*| 
¡  |�rX| 
¡  n|�rH| 
¡  |�rV| 
¡  0 dS )a�  
    Check and update daily login streak.
    Called when player connects to server.

    Args:
        player_id: The player's ID

    Returns:
        dict with keys:
        - reward_available: bool, whether reward can be claimed
        - streak: int, current streak count
        - reward: dict or None, today's reward details
        - streak_broken: bool, whether streak was broken today
    NT©Ú
dictionaryú6SELECT * FROM player_login_streak WHERE player_id = %szªINSERT INTO player_login_streak
                   (player_id, current_streak, last_login_date, total_logins, next_reward_day)
                   VALUES (%s, 1, %s, 1, 1)r   úPlayer z first login - starting streakF)Zreward_availableZstreakr$   Ústreak_brokenÚlast_login_dateÚcurrent_streakÚnext_reward_dayr   z streak broken after z dayszÅUPDATE player_login_streak
               SET current_streak = %s, last_login_date = %s,
                   total_logins = total_logins + 1, next_reward_day = %s
               WHERE player_id = %sz daily login - streak: z, day: z&Error checking daily login for player ú: r   r   )r   Útodayr   ÚcursorÚexecuteÚfetchoneÚcommitÚget_daily_rewardr   r    ÚcloseÚdaysr"   r#   )r)   Úconnr5   r4   Ústreak_datar$   Ú
last_loginZdays_since_loginr/   Z
new_streakZnext_dayr%   r&   r&   r'   Úcheck_daily_login6   s®    þüüA¼ü6Ç


û üìüõ
ýr?   )Ú
day_numberr*   c              
   C   sJ  d}d}�zzžt ƒ }|jdd�}| d| f¡ | ¡ }|sjt d| › �¡ W W |rZ| ¡  |rf| ¡  dS |d |d |d | d	¡|d
 dœW W |rž| ¡  |rª| ¡  S  t�y } zBtj	d| › d|› �dd� W Y d}~W |rî| ¡  |rú| ¡  dS d}~0 0 W |�r| ¡  |�rF| ¡  n|�r6| ¡  |�rD| ¡  0 dS )zš
    Get reward for specific day.

    Args:
        day_number: Day number (1-7)

    Returns:
        Dict with reward details or None if not found
    NTr+   z7SELECT * FROM daily_login_rewards WHERE day_number = %szDaily reward not found for day r@   Úreward_typeÚreward_amountZreward_item_idÚdisplay_name)r   r   r   Zitem_idr   z#Error getting daily reward for day r3   r   )
r   r5   r6   r7   r   Úwarningr:   Úgetr"   r#   )r@   r<   r5   r$   r%   r&   r&   r'   r9   ©   sZ    
þîûðú
ýr9   c           
   
   C   s¬  d}d}�z~�zât ƒ }|jdd�}| d| f¡ | ¡ }|sdddddœW W |rV| ¡  |rb| ¡  S |d t ¡ krt|d	 d
krˆ|d	 nd}t|ƒ}|sÀddddœW W |r²| ¡  |r¾| ¡  S |d dkrðd
dlm	} || d|› �|d ƒ nÀ|d dk�r| d|d | f¡ | 
¡  n”|d dk�rH| d|d | f¡ | 
¡  nh|d dk�r°| d¡ | ¡ }|�r°|d
 }| d| |d f¡ | 
¡  t d| › d| dd¡› �¡ t d| › d|› �¡ d|ddœW W |�râ| ¡  |�rð| ¡  S  t�yh }	 z^|�r| ¡  tjd | › d!|	› �dd"� ddd#dœW  Y d}	~	W |�rP| ¡  |�r^| ¡  S d}	~	0 0 W |�rz| ¡  |�r¨| ¡  n|�r˜| ¡  |�r¦| ¡  0 dS )$z÷
    Claim today's reward.
    Awards the reward to player and marks as claimed.

    Args:
        player_id: The player's ID

    Returns:
        dict with keys:
        - success: bool
        - reward: dict or None
        - message: str
    NTr+   r-   FzNo login streak found)Zsuccessr$   Úmessager0   r2   r   r   zReward not foundr   r	   )Úaward_diamondsZdaily_reward_dayr   r   zHUPDATE players SET energy = LEAST(energy + %s, max_energy) WHERE id = %sÚprestigez9UPDATE players SET prestige = prestige + %s WHERE id = %sÚitemzKSELECT * FROM store_items WHERE category = 'luxury' ORDER BY RAND() LIMIT 1z¬INSERT INTO player_inventory (player_id, item_id, quantity)
                       VALUES (%s, %s, 1)
                       ON DUPLICATE KEY UPDATE quantity = quantity + 1Úidr.   z received luxury item: r   Úunknownz claimed daily reward: Day zReward claimed successfullyz'Error claiming daily reward for player r3   r   zServer error)r   r5   r6   r7   r:   r   r4   r9   Úmonetization.diamond_economyrG   r8   Úfetchallr   r    rE   r"   Úrollbackr#   )
r)   r<   r5   r=   Z
reward_dayr$   rG   Zluxury_itemsrI   r%   r&   r&   r'   Úclaim_daily_reward×   s¸    þýU¨	ý?¾
þ

þ
ÿ
üýìýö
ýrO   c              
   C   st  d}d}t  ¡ }�z>�zztƒ }|jdd�}| d| f¡ | ¡ }|sRd}d}d}n|d }|d }|d }|rv||knd	}| }	| d
¡ | ¡ }
g }|
D ]~}|d }|d }|d }||k pÈ||koÈ|}||dkrØ|nd|dkræ|nd|dkrô|nd|dk�rdnd|dœ}| |¡ qš|tdd� }ddl	m	} | 
||j ¡ ¡ ¡ }|�rX| ¡ n| ¡ }||||	||dœW W |�r‚| ¡  |�r�| ¡  S  t�y0 } z†tjd| › d|› �dd� ddl	m	} |tdd� }d| ¡ | 
||j ¡ ¡ ¡ dd	g dœW  Y d}~W |�r| ¡  |�r&| ¡  S d}~0 0 W |�rB| ¡  |�rp| ¡  n|�r`| ¡  |�rn| ¡  0 dS )zÀ
    Get complete daily reward state for iOS DailyRewardState model.

    Args:
        player_id: The player's ID

    Returns:
        Dictionary matching iOS DailyRewardState structure
    NTr+   zƒSELECT current_streak, last_login_date, next_reward_day
               FROM player_login_streak
               WHERE player_id = %sr   r1   r0   r2   Fz†SELECT day_number, reward_type, reward_amount, display_name
               FROM daily_login_rewards
               ORDER BY day_numberr@   rA   rB   r	   r   r   Úmoneyr
   zLuxury Item)rJ   r	   r   rP   Z	bonusItemÚclaimed)r;   )Údatetime)ZcurrentStreakZlastLoginDateZnextResetDateZcanClaimZtodaysClaimedÚrewardsz,Error getting daily reward state for player r3   r   )r   r4   r   r5   r6   r7   rM   Úappendr   rR   ÚcombineÚminÚtimeÚ	isoformatr:   r"   r   r#   )r)   r<   r5   r4   Zstreak_infor1   r>   r2   Ztodays_claimedZ	can_claimZreward_definitionsrS   Z
reward_defZday_numrA   r   rQ   Z
day_rewardZtomorrowrR   Z
next_resetZlast_login_strr%   r&   r&   r'   Úget_daily_reward_stateO  sœ    
üÿúúå	ú
ó

ýrY   )r)   c              
   C   sz   z6t | ƒ t| ƒ}|| ddi|¥ƒ t d| › �¡ W n> tyt } z&tjd| › d|› �dd� W Y d}~n
d}~0 0 dS )	zá
    WebSocket handler for daily login check.
    Called when player connects to server.

    Args:
        player_id: The player's ID
        send_to_client: Function to send messages to client (player_id, message_dict)
    r   ZdailyRewardStatusz"Sent daily reward state to player z,Error handling daily login check for player r3   Tr   N)r?   rY   r   r    r"   r#   )r)   Zsend_to_clientÚstater%   r&   r&   r'   Úhandle_daily_login_check¸  s    	ÿþr[   c              
   C   s\  d}d}�z.z t ƒ }|jdd�}| d| f¡ | ¡ }|sddddddœW W |rV| ¡  |rb| ¡  S |d |d	 |d
 |d rŠ|d  ¡ nddœW W |r | ¡  |r¬| ¡  S  t�y } zRtjd| › d|› �dd� dddddœW  Y d}~W |�r | ¡  |�r| ¡  S d}~0 0 W |�r*| ¡  |�rX| ¡  n|�rH| ¡  |�rV| ¡  0 dS )zŠ
    Get player's login streak information.

    Args:
        player_id: The player's ID

    Returns:
        dict with streak info
    NTr+   r-   r   r   )r1   Útotal_loginsr2   r0   r1   r\   r2   r0   z%Error getting streak info for player r3   r   )	r   r5   r6   r7   r:   rX   r"   r   r#   )r)   r<   r5   r=   r%   r&   r&   r'   Úget_login_streak_infoÔ  sf    
þüåüìüõ
ýr]   )r*   c               
   C   sÜ   d} d}z´z@t ƒ } | jdd�}| d¡ | ¡ W W |r>| ¡  | rJ|  ¡  S  ty  } z>tjd|› �dd� g W  Y d}~W |rŠ| ¡  | r–|  ¡  S d}~0 0 W |r°| ¡  | rØ|  ¡  n|rÊ| ¡  | rÖ|  ¡  0 dS )z]
    Get all daily reward definitions.

    Returns:
        List of reward dictionaries
    NTr+   z5SELECT * FROM daily_login_rewards ORDER BY day_numberzError getting all rewards: r   )r   r5   r6   rM   r:   r"   r   r#   )r<   r5   r%   r&   r&   r'   Úget_all_rewards
  s<    ÿ
öú
ýr^   )Ú__doc__Útypingr   r   r   rR   r   r   r   ÚrandomÚasyncioÚdatabase.db_operationsr   r   r(   ÚintÚstrr?   r9   rO   rY   r[   r]   Úlistr^   r&   r&   r&   r'   Ú<module>   s,   ùs.xi6