o
    g+                     @   sV  d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlZd dlm Z  d$dede!fddZ"dede!dedefddZ#dede!fddZ$dede!de!defddZ%dede!dee fdd Z&dede!d!efd"d#Z'dS )%    )Session)func)
StepRecord)StepRecordCreate)UserService)get_setting_floatget_setting_int)datedatetime	timedelta)List)settings)PointTransaction)
UserPoints)UserReferral)now)point_serviceN)ExpoPushNotificationServicedbstepsc                 C   sT   t | d|}t| d|}t | d|}||krt|| S t|| || | |  S )NSTEP_BASE_RATESTEP_THRESHOLDSTEP_MULTIPLIER)r   r   int)r   r   country_codeZ	base_rate	thresholdZ
multiplier r   (/app/app/services/step_record_service.pyconvert_steps_to_points   s   r   user_id	step_datareturnc              
   C   sB  ddl m} | ||j|k }|r|jnd}| ttj|ktj	|j	k }t
| |j|}|rM|j|_||_|j|_|j|_|j|_|j|_nt||j	|j||j|j|j|jd}| | | ttj|k }|dkrt| d|}	tj| ||	d |   | | t
| ||}
|
drt|
d	 |S )
u   
    사용자의 특정 날짜에 걸음 기록을 생성하거나 업데이트합니다.
    포인트 계산은 하지만 실시간으로 적립하지 않습니다.
    r   UserNr   record_datesteps_countpoints_earnedcalories_burneddistance_kmgoal_achievedsync_source   REFERRAL_BONUSreferred_user_idbonus_pointssuccessmessage)app.models.userr#   queryfilteridfirstr   r   r   r%   r   r&   r'   r(   r)   r*   r+   addcountr   r   award_referral_bonuscommitrefreshr   getprint)r   r   r    r#   userr   recordr'   Ztotal_recordsreferral_bonusconversion_resultr   r   r   create_step_record   sL   






rC   c                 C   s*   |  ttj|ktjt k }|S )zr
    Retrieves the step record for the given user for the current date.
    Returns None if no record exists.
    )r4   r   r5   r   r%   r	   todayr7   )r   r   r@   r   r   r   get_current_step_recordW   s   
rE   steps_incrementc              
   C   sN  ddl m} | ||j|k }|r|jnd}| ttj|ktj	t
 k }|rA| j|7  _t| |j|}||_nt|t
 |t| ||ddddd}| | |   | | | ttj|k }|r|jst| d|}	tj| ||	d	 |r|jr|jnt| d
|}
tt}|d| d|j d|
 d|j  t| d|}|js|j|
krt|d|d|
 dd}| | | ttj|k }|r| j |7  _ nt||d}| | d|_|   | tj!|dd"tj#$  }|d|  t%| ||}|&drt'|&d t(| || |S )u  
    Accumulates steps for the current day's record for the given user.
    If a record exists, the new steps are added to the existing value.
    Otherwise, a new record is created.
    포인트 계산은 하지만 실시간으로 적립하지 않습니다.
    r   r"   Ng        Fzreal-time-updater$   r-   r.   ACHIEVEMENT_STEP_GOALz"[Achievement Bonus Check] user_id=z, steps_count=z, daily_goal=z, goal_achieved=ACHIEVEMENT_BONUSachievementz-Achievement bonus for reaching daily goal of z steps)r   transaction_typeamountdescription)r   total_pointsT)r   rJ   z)Achievement bonus transaction committed: r1   r2   ))r3   r#   r4   r5   r6   r7   r   r   r   r%   r	   rD   r&   r   r'   r8   r;   r<   r   r/   awardedr   r   r:   daily_step_goallogging	getLogger__name__infor*   r   r   rM   	filter_byorder_by
created_atdescr   r=   r>    check_and_send_step_notification)r   r   rF   r#   r?   r   r@   Zcurrent_pointsreferralrA   Z
daily_goalloggerZachievement_bonusZachievement_txuser_points_recordZachievement_entryrB   r   r   r   update_step_record_accumulationb   sx   







&


$r\   c                 C   s*   |  ttj|ktj  }|S )z
    Retrieves all step records for the given user across all dates.
    Records are ordered by record_date in descending order.
    )r4   r   r5   r   rU   r%   rW   all)r   r   recordsr   r   r   get_all_step_records   s   
r_   step_recordc              	   C   s&  ddl m} | ||j|k }|sdS t }|j}|j	du s*|j	 |k r-d|_
|j
|kr4dS |j}|j}|| d }	d}
|j	du pRt |j	 t|
dk}|	dk r|r|| }t|	 d}d	}d
| d| d}tj| |||d||dd t |_	| j
d7  _
|   dS dS dS )u   
    사용자의 현재 걸음수를 확인하고, 목표에 미달하는 경우 설정된 빈도에 따라 알림을 보냅니다.
    r   r"   Nd      )hoursP   %u   Adım Hedefi Bildirimiu    Bugün hedef adım sayısının u4   'ini yalnızca başardınız. Hedefe ulaşmak için u    adım daha atmanız gerekiyor!Zstep_reminder)current_steps
goal_steps)r   r   titler2   notification_typedatar,   )r3   r#   r4   r5   r6   r7   r	   rD   step_notification_frequencylast_step_notification_timestep_notifications_sent_todayr&   rO   r
   r   r   r   r   send_push_to_userr;   )r   r   r`   r#   r?   rD   Zmax_notificationsrf   rg   Zstep_percentageZmin_hours_between_notificationsZcan_send_notificationZremaining_stepsZpercentage_textrh   r2   r   r   r   rX      sD   



rX   )N)(sqlalchemy.ormr   
sqlalchemyr   app.models.step_recordr   app.schemas.step_recordr   app.services.user_servicer   app.services.admin_servicer   r   r
   r	   r   typingr   app.core.configr   Zapp.models.point_transactionr   Zapp.models.user_pointsr   Zapp.models.user_referralr   app.core.timer   app.servicesr   rP   +app.services.expo_push_notification_servicer   r   r   rC   rE   r\   r_   rX   r   r   r   r   <module>   s,    
:`
