
    soj                        d dl Z d dl m Z  d dl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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 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.m/Z/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7 d dl8m9Z9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@mAZAmBZB d dlCmDZD 	 dRd!ejE        d"ed#eFd$dfd%ZG	 	 	 dSd"ed'eFd(ed)eFd$eHf
d*ZI	 	 	 dTd"ed(ed+eJe         d,eFd'eFd$eHfd-ZKd!ejE        d"ed$dfd.ZLd!ejE        d"efd/ZM	 dUd"ed0e d$eJe         fd1ZNd!ejE        d"ed$dfd2ZO	 dUd!ejE        d"ed3e	d$dfd4ZPd"ed(ed$eJe         fd5ZQd"ed$eJe         fd6ZR	 	 dVd7ed8eJe         d9eFd$eSfd:ZTd!ejE        d$dfd;ZUd!ejE        d$dfd<ZVd!ejE        d$dfd=ZWd"ed(ed$eFfd>ZXd"ed(ed$efd?ZYd"ed(ed$eSfd@ZZ	 dUdAed(edBeSdCed$ef
dDZ[d(ed7ed$dfdEZ\d(edAed$dfdFZ]	 	 	 dWd7ed"ed(ed$eSfdGZ^d3e	dHeSd$edz  fdIZ_	 	 	 	 dXd!ejE        dJeHd"edKeFd3e	f
dLZ`	 	 dYd!ejE        d"edJeHdKeFd3e	f
dMZad"ed$e-fdNZbd"efdOZcd!ejE        d(ed"ed$eHfdPZdd"ed3e	d$eFfdQZedS )Z    N)datetime)
BadRequestTelegramError)ContextTypes)	GroupChat)
Prediction)PredictionGroupChatMessage)PredictionOption)PredictionOptionUser)User)ContextDataKey)Emoji)Feature)PredictionResultNotification PredictionBetInvalidNotification)PredictionStatus!get_prediction_status_name_by_key)PredictionType)Screen)DevilFruitAbilityType)IncomeTaxEventType)PredictionException)ContextDataValue)Keyboard)round_belly_upadd_or_remove_bounty)default_datetime_format)get_ability_value)0broadcast_to_chats_with_feature_enabled_dispatchsave_group_chat_error)escape_valid_markdown_charsfull_message_send)send_notification)'get_random_user_context_inner_query_key)get_percentage_from_valueget_value_from_percentageadd_percentage_to_value)get_belly_formattedFcontext
prediction	is_resentreturnc           	      ~  K   |sbt          |j                  t           j        urt          t          j                  t           j        |_        t          j                    |_	        |
                                 t          |          }t          | t          j        ||t          |          gg           d{V  dS )z
    Send prediction
    :param context: Telegram context
    :param prediction: Prediction
    :param is_resent: If prediction was already sent
    )external_iteminline_keyboardN)r   statusNEWr   phrasesPREDICTION_NOT_IN_NEW_STATUSSENTr   now	send_datesaveget_prediction_textr   r   
PREDICTIONget_prediction_deeplink_button)r)   r*   r+   texts       &/app/src/service/prediction_service.pysendr=   /   s        .J-..6F6JJJ%g&JKKK,1
'|~~
OOz**D
: 8DDEF               Tadd_bets_commanduseris_creator_recapc                    |rd}| j         duo
|| j         k    }|o|                                 t          j        u }|s| j        du o| j         duo
|| j         k    }d}d}|s|s| j        }t          |           }	t          d |	D                       }t          |          D ]\  }
fd|	D             }t          d |D                       }|t          j
                            j        t          j                  t          ||d          j        rt"          j        nd          z  }n| j        Nt          | j                  D ]8\  }
}|t          j                            |
d	z   t          |                    z  }9nV| j        }t          |          D ]?\  }
|t          j                            j        t          j                            z  }@|| j        d
ndz  }d}|s|| j        2t          j                            t/          | j        |                    ndz  }|rx|                                 t          j        u rX|t          j                            | j        t/          | j        |          nt          j                  z  }|t          j        z  }n|| j        2t          j                            t/          | j        |                    ndz  }n|t          j                            | j        t/          | j        |          nt          j                  z  }|t          j                            | j        t/          | j        |          nt          j                  z  }d}t?          | j                   t>          j!        ur| j"        rTt"          j#        }|tI          | |          }n| j%        }t          j&                            tO          |                    }nt"          j(        }d}|t          j)                            ||          z  }| j*        rt"          j#        nt"          j(        }|t          j+                            |          z  }|r|t          j,        z  }||rd
ndz  }| j-        rt"          j#        nt"          j(        }|t          j.                            |          z  }|r|t          j/        z  }|r]||rd
ndz  }| j0        rt"          j#        nt"          j(        }|t          j1                            |          z  }||rt          j2        ndz  }d}d}|r?t          | j3                  t          j4        u rt          j5        }| j-        rt          j6        }|dk    rd
|z   nd}||z  }d}t?          | j                   t>          j!        u r|st          j7        }| j        i|sg|set          j8                            t          | j9                  |tO          |          tu          t          | j3                            ||||          }n8||z  }t          j;                            t          | j9                  ||          }|S )aw  
    Get prediction text
    :param prediction: Prediction
    :param add_bets_command: If to add commands on how to place and remove bets
    :param user: User, if called from private chat and prediction max refund should be customized
    by DF ability
    :param is_creator_recap: If the prediction is being sent to the creator as a recap
    :return: Prediction text
    FN r   c              3   $   K   | ]}|j         V  d S Nwager.0prediction_option_users     r<   	<genexpr>z&get_prediction_text.<locals>.<genexpr>o   s7       
 
-C"(
 
 
 
 
 
r>   c                 >    g | ]}|j         j        j        k    |S  )prediction_optionid)rI   rJ   rN   s     r<   
<listcomp>z'get_prediction_text.<locals>.<listcomp>t   s;     C C C*);>BSBVVV 'VVVr>   c              3   $   K   | ]}|j         V  d S rE   rF   rH   s     r<   rK   z&get_prediction_text.<locals>.<genexpr>y   s7        1G&,     r>   )add_decimal   
r*   r@   )<creator
get_statusr   r1   rO   prediction_optionsget_prediction_options_userssum	enumerater2   &PREDICTION_TEXT_OPTION_WITH_PERCENTAGEformatnumberr!   optionr%   
is_correctr   CORRECToptionsPREDICTION_TEXT_OPTIONend_datePREDICTION_CLOSING_DATEr   BETS_CLOSEDPREDICTION_CREATE_CUT_OFF_DATEcut_off_dateTEXT_NOT_SET"PREDICTION_CUT_OFF_DATE_HOW_TO_SETPREDICTION_CUT_OFF_DATEPREDICTION_CREATE_CLOSE_DATEr   typeUSERrefund_wagerPREDICTION_FEATURE_ENABLEDget_max_wager_refundmax_refund_wagerPREDICTION_WAGERS_REFUNDED_MAXr(   PREDICTION_FEATURE_DISABLEDPREDICTION_WAGERS_REFUNDEDallow_multiple_choices PREDICTION_MULTIPLE_BETS_ALLOWED,PREDICTION_MULTIPLE_BETS_ALLOWED_DESCRIPTIONcan_withdraw_betPREDICTION_CAN_WITHDRAW_BETS(PREDICTION_CAN_WITHDRAW_BETS_DESCRIPTION	is_publicPREDICTION_IS_PUBLIC PREDICTION_IS_PUBLIC_DESCRIPTIONr0   r4   PREDICTION_BET_HOW_TO_PLACE_BET%PREDICTION_BET_HOW_TO_REMOVE_ALL_BETSPREDICTION_USER_DISCLAIMERPREDICTION_TEXTquestionr   PREDICTION_CREATE_RECAP)r*   r?   r@   rA   
is_creatoris_creator_but_not_sentoptions_texttotal_wagerrX   prediction_options_usersindexprediction_option_usersoption_wagerr_   
added_textoptional_textenabled_emojirr   max_refund_texthow_to_bet_command_texthow_to_remove_bet_command_textuser_prediction_disclaimerprediction_textrN   s                          @r<   r8   r8   M   sm      ! #4/NDJ<N4NJ(\Z-B-B-D-DHXH\-\ 
MT!cj&8&DcQ[QcIc 	
 LK &H 7 &H5?5R?[@
 @
   
 
G_
 
 
 
 
 )22D(E(E 	 	$E$C C C C.FC C C#
   Kb    L GJQQ!(+,=,DEE),QVWWW"3">FB	  LL	  = !*:+=!>!>  v > E EAI/77! !  :D9V,56H,I,I  (( > E E%,/0A0HII! !  	
 3 ?RGJ  $
 ". +22'
(;TBB   	

  	*//115E5QQQ'@GG*6 (
(?FFF)  J
 'DDJJ *6 /66+J,CTJJ   JJ 	g:AA". $J$7>>>%
 
 	

 	g<CC&2 $J$;TBBB%
 
 	

 M jo&&n.AAA" 	!!<M#7:TX#Y#Y#Y  #-#> %DKK#$455 OO "=M O;BB=Rabbb
 ,	/((. 
 W=DD]SSSM NMM -5TT25M &	/((. 
 W9@@OOOM JII  ^!19r9 #3E,,2 	
 	5<<]KKKEU]AA[]] !%'" _J-..2B2GGG&-&M#* _181^. -:R,?,?D=((RM-J "$jo&&.*===j=%,%G" } )@ IY !188'
(;<<,,-.>z?P.Q.QRR#*&	
 	
 	00
!9@@'
(;<<lJ
 
 r>   prediction_options_user
add_headerc           	         t          | j                  t           j        u rdS |t          | |          }t	          |          dk    rt
          j        S d}d}d}t          | j                  }|rt
          j        nd}	|D ]'}
|
j        }|	t
          j	        
                    |j        t          |j                  t          |
j                            z  }	|t           j        u}t#          |
|          }t          |          }|t           j        ur#|	t
          j        
                    |          z  }	|j        r-|	t
          j        
                    |          z  }	||z  }|dz  }|	t
          j        z  }	|| j        s|
j        ndz  }|dz  }| j        r|	t
          j        z  }	)t	          |          dk    r|t           j        u r|dk    rf|dk    r0|	t
          j        
                    t          |                    z  }	n|	t
          j        
                    t          |                    z  }	nt5          |          }|dk    r0|	t
          j        
                    t          |                    z  }	nV|	t
          j        
                    t          |                    z  }	n&|r$|t           j        u r| j        r|	t
          j        z  }	|r$|t           j        u r| j        r|	t
          j         z  }	|	S )aW  
    Get the prediction status text
    :param prediction: The prediction
    :param user: The user
    :param prediction_options_user: The options the user has bet on
    :param add_header: Whether to add the "Bets" header
    :param add_bets_command: Whether to add the command to remove all bets
    :return: The prediction status text
    rC   Nr   )is_potentialrS   )!r   r0   r1   get_prediction_options_userlenr2   PREDICTION_BET_USER_HAS_NOT_BETPREDICTION_STATUS_BETS_HEADERrN   PREDICTION_STATUS_OPTIONr]   r^   r!   r_   r(   rG   
RESULT_SETget_prediction_option_user_winPREDICTION_STATUS_POTENTIAL_WINr`   PREDICTION_STATUS_RESULT_WINPREDICTION_STATUS_RESULT_LOSTro   &PREDICTION_STATUS_RESULT_LOSS_REFUNDEDPREDICTION_STATUS_NET_WINPREDICTION_STATUS_TOTAL_WINabsPREDICTION_STATUS_NET_LOSSPREDICTION_STATUS_TOTAL_LOSSr4   ry    PREDICTION_BET_HOW_TO_REMOVE_BETr   )r*   r@   r   r   r?   total_win_amounttotal_win_counttotal_loss_countprediction_statusot_textrJ   rN   r   potential_win_amountpotential_win_amount_formattedtotal_loss_amounts                   r<   get_user_prediction_status_textr     sv   " 
)**.>.BBBr&"=j$"O"O
"##q((66O*::;L*M*M7AIg33rG"9 )N )N.D.V 	73::$'(9(@AA 6 <==
 
 	
 )0@0KK=" 
  
  
 *==Q)R)R& $4$???w>EE.  GG
 !+ N7?FF2   !$88 1$7@@ 8B8OV*00UV  !A%  * NwMMG "##a'' 0 ;;;1$$#a''w@GG+,<==    GG wBII+,<==    GG %((8$9$9!"Q&&wAHH+,=>>    GG wCJJ+,=>>    GG
 	@!%5%:::+ ; w??G 	A!1!666' 7 	7@@Nr>   c                   K   t          |j                  t           j        urt          t          j                  t          | |           d{V  t           j        |_        t          j	                    |_
        |                                 t          | |           d{V  t          | t          j        |           d{V  dS )z[
    Close bets
    :param context: Telegram context
    :param prediction: Prediction
    N)r   r0   r4   r   r2   PREDICTION_NOT_IN_SENT_STATUScut_off_invalid_betsrf   r   r5   rd   r7   refresh9send_prediction_status_change_message_or_refresh_dispatchPREDICTION_CLOSED_FOR_BETS)r)   r*   s     r<   
close_betsr     s       
)**2B2GGG!'"GHHH
w

3
33333333 )4J",..JOO ':
&
&&&&&&&& D3Z          r>   c                 H  K   i }|j         t          |          }|D ]}|j        }t          ||j        d           d{V  |                                 |j        |vr|g dg||j        <   ||j                 d                             |           ||j                 dxx         |j        z  cc<   |                                 |	                                D ]E\  }}|d         }|d         }|d         }	t          |||	          }
t          | ||
           d{V  FdS )z
    Cut off invalid bets (bets placed after cut off date), notifying the users
    :param context: Telegram context
    :param prediction: Prediction
    :return: None
    NTshould_affect_pending_bountyr   rS      )rh   get_invalid_betsr@   r   rG   r7   rO   appenddelete_instanceitemsr   r#   )r)   r*    users_invalid_prediction_optionsinvalid_prediction_option_usersinvalid_prediction_option_userr@   user_idvaluer   total_refundnotifications              r<   r   r     s      \^$ *FVWaFbFb'.M 	= 	=*7<D&4:Y]          IIKKK w>>>=A2qM09,TW5a8??@^___,TW5a888<Z<``888*::<<<< ;@@BB 	= 	=1X"'(Qx9Y/:
 :
  |<<<<<<<<<<	= 	=r>   rh   c                     || j         t          d          | j         }t          j                                        t          j        | k    t          j        |k    z            S )z
    Get invalid bets (bets placed after cut off date)
    :param prediction: Prediction
    :param cut_off_date: Cut off date
    :return: List of invalid bets
    Nz>cut_off_date cannot be None if prediction.cut_off_date is None)rh   
ValueErrorr   selectwherer*   date)r*   rh   s     r<   r   r     sf     "*]^^^!.&((..		(J	6$|3	5  r>   c                   K   t          |j                  t           j        urt          t          j                  |j        }d |D             }t          |          }i }|D ]X}|j        }|j	        |vr|dg g||j	        <   |j
        }||j	                 d                             |           |j        r[t          ||          }	t          ||	|j        t           j        |j	                   d{V  ||j	                 dxx         |	z  cc<   n ||j	                 dxx         |j        z  cc<   |j        st'          |          dk    r[t'          |          dk    r|j        }
n#t)          |j        t+          |                    }
t          ||
|j        	           d{V  |                                 Zt           j        |_        t1          j                    |_        |                                 t7          | |           d{V  t9          | t          j        |           d{V  |                                D ]G\  }}|d         }|d         }|d         }t?          |||||          }tA          | ||           d{V  HdS )
z\
    Set results
    :param context: Telegram context
    :param prediction: Prediction
    c                      g | ]}|j         	|S rM   )r`   )rI   rN   s     r<   rP   zset_results.<locals>.<listcomp>  s1     : : :':: : :r>   r   r   )r   )pending_belly_amounttax_event_typeevent_idNrS   )rJ   )r   )!r   r0   rf   r   r2   $PREDICTION_NOT_IN_BETS_CLOSED_STATUSrX   rY   r@   rO   rN   r   r`   r   r   rG   r   r9   ro   r   minrq   r7   r   r   r5   result_set_dater   r   PREDICTION_RESULTS_SETr   r   r#   )r)   r*   rX   prediction_options_correctr   users_total_winrJ   r@   rN   
win_amountrefund_amountr   r   	total_winuser_prediction_optionsr   s                   r<   set_resultsr     sq      
)**2B2NNN!'"NOOO1;1N: :!3: : :
 <XXb;c;c (*O": / /+0 7/))(,a}ODG$ /E.V #**+<=== ' 	H7&AY  J '%;%A1<#          DG$Q''':5'''' DG$Q'''+A+GG''' " 	c*D&E&E&J&J-..!33 6 < !$*0(@VWWW! !
 'm:P:V          			 )3J!)JOO ':
&
&&&&&&&& D/        
 *//11 	= 	=1Xq	:?(5Q/1KYX\6
 6
  |<<<<<<<<<<	= 	=r>   
group_chatc                    K   t          |j                  t           j        u rt          t          j                  t          | |d|           d{V  dS )z
    Refresh prediction
    :param context: Telegram context
    :param prediction: Prediction
    :param group_chat: Group chat, refresh only for this group chat
    T)r*   should_refreshr   N)r   r0   r1   r   r2   PREDICTION_NOT_SENTr   )r)   r*   r   s      r<   r   r   D  s{       
)**.>.BBB!'"=>>>
CJt
           r>   c                    t          j                                        t                                        t           j        | k    t           j        |k    z                                t          j        	                                          }|S )z
    Get all prediction options for a user
    :param prediction: Prediction
    :param user: User
    :return: List of prediction options user
    )
r   r   joinr
   r   r*   r@   order_byr^   asc)r*   r@   results      r<   r   r   U  sr     	#%%				!,
:?S?X\`?`a

 

 
")--//	0	0  Mr>   c                 j    t          j                                        t           j        | k              S )z
    Get all prediction options users for a prediction
    :param prediction: Prediction
    :return: List of prediction options users
    )r   r   r   r*   )r*   s    r<   rY   rY   i  s+      &((../C/NR\/\]]]r>   rJ   r   r   c                 8    |t           j                  }t          d |D                       }|st          d |D                       }nt           fd|D                       }t           j        |          }t          t          ||                    }|S )ad  
    Get prediction option user potential win
    :param prediction_option_user: PredictionOptionUser for which to get potential win
    :param prediction_options_users: List of PredictionOptionUser for the same prediction
    :param is_potential: If True, assume that the prediction option is correct
    :return: Prediction option user potential win
    Nc              3   $   K   | ]}|j         V  d S rE   rF   rH   s     r<   rK   z1get_prediction_option_user_win.<locals>.<genexpr>  s7        )?$     r>   c              3   <   K   | ]}|j         j        |j        V  d S rE   )rN   r`   rG   )rI   pous     r<   rK   z1get_prediction_option_user_win.<locals>.<genexpr>  sC       "
 "
S=R=]"
I"
 "
 "
 "
 "
 "
r>   c              3   F   K   | ]}|j         j         k    |j        V  d S rE   )rN   rG   )rI   r   rJ   s     r<   rK   z1get_prediction_option_user_win.<locals>.<genexpr>  sC       "
 "
$(>(PPP IPPPP"
 "
r>   )rY   r*   rZ   r%   rG   r   r&   )rJ   r   r   r   total_correct_wagerpercentage_of_correct_wagervalue_from_total_wagers   `      r<   r   r   r  s      '#?@V@a#b#b   C[    K  	
! "
 "
!9"
 "
 "
 
 
 " "
 "
 "
 "
/"
 "
 "
 
 
 #<$&9# #
 ,!+/JKK  "!r>   c                 @  K   t          j                                        t           j                            d          t           j        t          j                    k    z  t           j        t          j	        k    z            }|D ]}t          | |           d{V  dS )zI
    Send scheduled predictions
    :param context: Telegram context
    FN)r   r   r   r6   is_nullr   r5   r0   r   r1   r=   r)   predictionsr*   s      r<   send_scheduled_predictionsr     s       %/$5$7$7$=$=			%	%e	,	,8<>>1	3 0 44	6% %K " ( (
7J''''''''''( (r>   c                 @  K   t          j                                        t           j                            d          t           j        t          j                    k    z  t           j        t          j	        k    z            }|D ]}t          | |           d{V  dS )zJ
    Close scheduled predictions
    :param context: Telegram context
    FN)r   r   r   rd   r   r   r5   r0   r   r4   r   r   s      r<   close_scheduled_predictionsr     s       %/$5$7$7$=$=			$	$U	+	+(,..0	2 0 55	7% %K " . .
*----------. .r>   c                   K   t           j        t           j        g}t          j                                        t          j                            |                    }|D ]i}t          j	                                        t          j
        |k                                               t          | t          j        |           d{V  jdS )zj
    Remove all bets from active predictions due to bounty reset
    :param context: Telegram context
    N)r   r4   rf   r   r   r   r0   in_r   deleter*   executer   r2   ,PREDICTION_ALL_BETS_REMOVED_FOR_BOUNTY_RESET)r)   active_statusesr   r*   s       r<   'remove_all_bets_from_active_predictionsr     s       (,.>.JKO$.$5$7$7$=$=o..% %K " 
 

#%%++ +z9	
 	

')))GWI:
 
 	
 	
 	
 	
 	
 	
 	
 	
	
 
r>   c                 D    t          t          | |                    dk    S )z
    Check if user bet on prediction
    :param prediction: Prediction
    :param user: User
    :return: True if user bet on prediction
    r   )r   r   rU   s     r<   user_has_bet_on_predictionr     s"     *:t<<==AAr>   c                 Z   t          | j                  }t          | |          rb|t           j        u rt          j        S |t           j        u rt          j        S t          | |          }|dk    rt          j	        S t          j
        S |t           j        u rt          j        S t          j        S )z
    Get user prediction status emoji for a user
    :param prediction: Prediction
    :param user: User
    :return: User prediction status emoji
    r   )r   r0   r   r4   r   PREDICTION_OPENrf   PREDICTION_CLOSEDget_prediction_net_winLOG_POSITIVELOG_NEGATIVEr1   PREDICTION_NEWNULL)r*   r@   r   net_wins       r<    get_user_prediction_status_emojir	    s     )):;;!*d33  0 555(("2">>>**,Z>>G{{))))	.2	2	2##zr>   c                     t          | |          }t          | j                  t          j        urt	          d| j         d          d}|D ]-}|j        }|j        r|t          |          z  }#||j	        z  }.|S )z
    Get net win for a user, without considering refunds, only for predictions with result set
    :param prediction: Prediction
    :param user: User
    :return: Net win
    zPrediction z4 results are not set, so net win can't be calculatedr   )
r   r   r0   r   r   rO   rN   r`   r   rG   )r*   r@   r   r  r   rN   s         r<   r  r    s     ;VD; ; 
)**2B2MMM]*-]]]
 
 	
 G& ! !.1.C' 	!5c:::GGsy GGNr>   rN   rG   prediction_group_chat_messagec                   K   t          j        t           j        |k    t           j        | k    z            }||xj        |z  c_        n[t                      }| j        |_        | |_        ||_        ||_        t          |t          j        dd          }|dk    r|nd|_	        ||nd|_
        t          j                    |_        |                                 t          ||dd           d{V  |S )a  
    Save the prediction option user
    :param prediction_option: The prediction option
    :param user: The user
    :param wager: The wager
    :param prediction_group_chat_message: The prediction group chat message
    :return: The prediction option user
    Nr   T)add_to_valueF)addr   )r   get_or_noner@   rN   rG   r*   r   r   PREDICTION_WAGER_REFUNDmax_refund_wager_boostr  r   r5   r   r7   r   )rN   r@   rG   r  rJ   r  s         r<   save_prediction_option_userr    s<      4H3S		"d	*15FF	H4 4
 )$$-$$$ "6!7!7,=,H)3D0&*#',$!2'?QU"
 "
 "
 '=q&@&@""a 	5
 *G)R%%X\ 8 #+,..!!! tUTX
Y
Y
YYYYYYYY!!r>   c                    K   |j         j        }t          | |j        |                                            d{V  |                                 dS )z
    Delete a prediction option user
    :param user: The user object
    :param prediction_option_user: The prediction option user
    :return: None
    r   N)rN   r*   r   rG   is_result_setr   )r@   rJ   r*   s      r<   delete_prediction_option_userr  F  s       4EPJ
 $)3)A)A)C)C%C          **,,,,,r>   c                    K   t          j        t           j        | k    t           j        |k    z            }|t	          | |           d{V  dS dS )z
    Delete a prediction option for a user
    :param user: The user object
    :param prediction_option: The prediction option
    :return: None
    N)r   r  r@   rN   r  )r@   rN   rJ   s      r<   !delete_prediction_option_for_userr  ^  sr       4H3S		"d	*15FF	H4 4
 )+D2HIIIIIIIIIII *)r>   c                    | J||F||t          d          t          j        t          j        |k    t          j        |k    z            } | -t          t          |t          j        |j	                            S || j        }t          t          |j	        | j                            }t          |j	        |          S )a  
    Get the maximum wager refund for a prediction option user, considering the Devil Fruit ability
    boost
    :param prediction_option_user: The prediction option user
    :param prediction: The prediction
    :param user: The user
    :return: The maximum wager refund
    Nz>Prediction option user or prediction and user must be provided)r   r   r  r@   r*   intr   r   r  rr   r'   r  max)rJ   r*   r@   max_refund_boosteds       r<   rq   rq   p  s     %:+=]^^^7K7W!&$.3G3RV`3`a8
 8
 %+CZE` 
 
 	
 !7!B
')?)V	
 	
 
 z*,>???r>   
message_idc                 ~    t          j        t           j        | k    t           j        |k    z            }|dS |j        S )z
    Gets the prediction from the message id
    :param group_chat: The group chat
    :param message_id: The message id
    :return: The prediction
    N)r	   r  r   r  r*   )r   r  r  s      r<   get_prediction_from_message_idr    sK     	#.'2j@)4
BD	
 	
 " %,t(33r>   r;   r   c           
      R  K   ||g}n]|rLt          t          j                                        t          j        t
          j        k                        }nt          d          |D ]>}|rt          |          }| j	        
                    t          | ||||                     ?dS )aL  
    Dispatch a prediction status change message
    :param context: The context
    :param prediction: The prediction
    :param text: The text
    :param should_refresh: Whether to should_refresh the message instead of sending a new one
    :param group_chat: The group chat for which to refresh the message
    :return: None
    Nz4Either prediction or should_refresh must be provided)listr   r   r   r0   r   r4   r   r8   applicationcreate_task0send_prediction_status_change_message_or_refresh)r)   r;   r*   r   r   r   s         r<   r   r     s      " )3	 Q(,%%j&7;K;P&PQQ)
 )
 OPPP! 
 

 	3&z22D''<T>: 	
 	
 	
 	
	
 
r>   c           
         K   d}|t           j        |k    }t          j                                        t           j        |k    |z            }|D ]}|j        }	 |r/t          | |||j        t          |          gg           d{V  nt          | |||j        d           d{V  [# t          t          f$ rO}|r&t          |t                    rdt          |          v st          |t          |                     Y d}~d}~ww xY wdS )a  
    Send a prediction status change message to all group chats in which the prediction was sent or
    refresh the message
    :param context: The context
    :param prediction: The prediction
    :param text: The text
    :param should_refresh: Whether to should_refresh the message instead of sending a new one
    :param group_chat: The group chat for which to refresh the message
    :return: None
    TN)r   edit_message_idkeyboardF)r   reply_to_message_idallow_sending_without_replyzMessage is not modified)r	   r   r   r   r*   r"   r  r:   r   r   
isinstancestrr    )	r)   r*   r;   r   r   group_chat_filtermessagesmessagees	            r<   r#  r#    s     $ 6AZO1K1R1T1T1Z1Z	#	.*	<@QQ2 2H  : : ' 2
	: ')$+$6=jIIJK           ()(/(:05          z* 	: 	: 	: :q*--: .Q77%j#a&&999	:': :s   AB++D<ADDc                     ddl m} |j        | j        i}t	          | j                  }|t          j        u rt          j        nt          j	        }t          ||t          j        t          j        gd          S )zl
    Get the prediction deeplink button
    :param prediction: The prediction
    :return: The keyboard
    r   )PredictionDetailReservedKeysT)screenprevious_screen_listis_deeplink)1src.chat.private.screens.screen_prediction_detailr0  PREDICTION_IDrO   r   r0   r4   r2   &GRP_KEY_PREDICTION_BET_IN_PRIVATE_CHAT'GRP_KEY_PREDICTION_VIEW_IN_PRIVATE_CHATr   r   PVT_PREDICTION_DETAILPVT_PREDICTION)r*   r0  infor0   keyboard_texts        r<   r:   r:   
  s     _^^^^^.<jmLD/
0ABBF %*** 	66< 
 +$34   r>   c                    K   t          |           }|D ]}|j        }t          ||           d{V   |                                  dS )zU
    Delete a prediction
    :param prediction: The prediction
    :return: None
    N)rY   r@   r  r   )r*   r   rJ   r@   s       r<   delete_predictionr=  $  sr       ;WWa:b:b"9 J J+0+D2HIIIIIIIIII      r>   c                 $   t          |           }|                                t          j        u rt	          |          nd}t          t          j        t          |df|j	        |gg          }|
                    | t          j        ||           |S )z
    Get the share button url
    :param context: The context
    :param user: The user
    :param prediction: The prediction
    :return: The share button url
    NF)argsdescriptionr&  )	inner_key)r$   rW   r   r4   r:   r   r2   PREDICTION_INLINE_RESULT_SHAREr8   r   set_context_datar   INLINE_QUERY)r)   r@   r*   rA  r&  context_data_values         r<   get_share_textrF  5  s     8@@I   ""&6&;;; 	'z222  ,<.% '*, , , 	,.@I     r>   c                 l    t          j        t           j        | k    t           j        |k    z            duS )z
    Check if a prediction is sent to a group
    :param prediction: The prediction
    :param group_chat: The group chat
    :return: True if the prediction is sent to the group
    N)r	   r  r*   r   )r*   r   s     r<    prediction_is_sent_to_group_chatrH  T  s?     	#.'2j@)4
BD	
 	
 		r>   )F)TNF)NTTrE   )NF)NNN)NNFN)FN)fr   src.tg_compat.errorr   r   src.tg_compat.extr   resources.phrasesr2   src.model.GroupChatr   src.model.Predictionr   $src.model.PredictionGroupChatMessager	   src.model.PredictionOptionr
   src.model.PredictionOptionUserr   src.model.Userr   src.model.enums.ContextDataKeyr   src.model.enums.Emojir   src.model.enums.Featurer   src.model.enums.Notificationr   r    src.model.enums.PredictionStatusr   r   src.model.enums.PredictionTyper   src.model.enums.Screenr   1src.model.enums.devil_fruit.DevilFruitAbilityTyper   -src.model.enums.income_tax.IncomeTaxEventTyper   src.model.error.CustomExceptionr   src.model.pojo.ContextDataValuer   src.model.pojo.Keyboardr   src.service.bounty_servicer   r   src.service.date_servicer   src.service.devil_fruit_servicer   src.service.group_servicer   r    src.service.message_servicer!   r"    src.service.notification_servicer#   src.utils.context_utilsr$   src.utils.math_utilsr%   r&   r'   src.utils.string_utilsr(   DEFAULT_TYPEboolr=   r*  r8   r   r   r   r   r   r   r   r   rY   r  r   r   r   r   r   r	  r  r  r  r  rq   r  r   r#  r:   r=  rF  rH  rM   r>   r<   <module>ri     s          9 9 9 9 9 9 9 9 * * * * * * # # # # # # ) ) ) ) ) ) + + + + + + K K K K K K 7 7 7 7 7 7 ? ? ? ? ? ?       9 9 9 9 9 9 ' ' ' ' ' ' + + + + + +        a ` ` ` ` ` ` ` 9 9 9 9 9 9 ) ) ) ) ) ) S S S S S S L L L L L L ? ? ? ? ? ? < < < < < < , , , , , , K K K K K K K K < < < < < < = = = = = =        W V V V V V V V > > > > > > K K K K K K         
 7 6 6 6 6 6 SX &4>KO	   @ ""	D DDD D 	D
 	D D D DT ;?!r rr
r ""67r 	r
 r 	r r r rjl7 Z TX    2*=(A *=z *= *= *= *=\ 6: *2	
   ,\=|8 \=j \=UY \= \= \= \=@ Y] &4>LU	   "J d tL`Ga    (^Z ^DAU<V ^ ^ ^ ^ <@)" )"0)""#78)" )" 		)" )" )" )"X(l.G (D ( ( ( (".|/H .T . . . ."
<;T 
Y] 
 
 
 
*B: BT Bd B B B B 4 E    4z  #    @ AE	-" -"'-"
-" -" $>	-"
 -" -" -" -"`-
-(<-	- - - -0J
J#3J	J J J J& 48!&@ &@0&@&@ &@ 		&@ &@ &@ &@R4y 4c 4j[_N_ 4 4 4 4. !  "
 "
&"

"
 "
 	"

 "
 "
 "
 "
R ! 4: 4:&4:4: 4: 	4:
 4: 4: 4: 4:nz h    4!
 ! ! ! !"L5 T z ^a    >  W[      r>   