
    tsi                     *   d Z ddlZddlmZmZmZmZmZ ddlm	Z	m
Z
 ddlmZ  ej                  d      Z	 dded	ed
eeeef      deeeef      dee   deeee   f   fdZd
eeeef      dedee   fdZdeeeef      d
eeeef      dee   fdZy)z
Reconciliation: cross-check player-team mappings across sources.

Detects:
- Player on wrong team (trade not reflected)
- Identity collisions (duplicate names)
- Market/official mismatches
    N)ListDictAnyOptionalTuple   )canonicalize_team_identifiernormalize_player_name)ConflictDetailzpub-integrityplayer_name	prop_teamroster_entriesmarket_propsleaguereturnc                 N   t        |       }t        ||      }d}|D ]4  }|j                  d      |k(  st        |j                  dd      |      } n |y|rF|rD||k7  r?t        d| |d||dd	d
|  d| d| 	      }	t        j                  d|  d| d|        d|	fS d}
|D ]4  }|j                  d      |k(  st        |j                  dd      |      }
 n |
rK|rI|
|k7  rDt        d| |d|xs d|
|ddd|  d|
 d| 
      }	t        j                  d|  d|
 d|        d|	fS y)zh
    Verify that a player is mapped to the correct team.

    Returns (is_valid, conflict_or_none).
    Nnormalized_nameteam )TNTEAM_MISMATCHcurrent_teamhighroster_reconciliationzPlayer z is on z+ per roster data, but prop assigns them to )	conflict_typer   	player_idfieldofficial_valueinternal_valueseveritysourcedetailz[reconcile] Team mismatch: z roster=z prop=FMARKET_TEAM_MISMATCHmarket_teamunknownmediummarket_reconciliationzMarket has z on z, prop has )
r   r   r   r   r   market_valuer   r   r    r!   z"[reconcile] Market team mismatch: z market=)r
   r	   getr   logwarning)r   r   r   r   r   	norm_name	norm_teamroster_teamentryconflictr#   mps               .scripts/publishing_integrity/reconciliation.pyreconcile_player_teamr2      s    &k2I,Y?I K 99&'946uyy7LfUK  y[I%=!)# &$*[M >//8k;
 	1+h{mSYZcYdefh K 66#$	16rvvfb7I6RK
 y[I%=!0#&3)$$* T+k)U
 	8Xk]Z`aj`klmh    c                    i }| D ]W  }|j                  dd      }t        |j                  dd      |      }|s4|s7|j                  |g       j                  |       Y g }|j	                         D ]z  \  }}t        t        |            }	t        |	      dkD  s)|j                  t        d||ddj                  |	      dd	d
| d|	              t        j                  d| d|	        | |S )zJDetect players with same normalized name on different teams (same league).r   r   r   r   IDENTITY_COLLISIONteam_assignmentz, r   identity_collision_checkPlayer 'z' appears on multiple teams: r   r   r   r   r   r   r    r!   z![reconcile] Identity collision: 'z' on teams )r(   r	   
setdefaultappenditemslistsetlenr   joinr)   r*   )
r   r   
name_teamsr.   normr   	conflictsr+   teamsunique_teamss
             r1   detect_identity_collisionsrF   X   s   
 (*J 9yy*B/+EIIfb,A6JD!!$+2248	9 I&,,. b	5CJ'|q ^2%#'#yy61!),I,X	 	 KK;I;kR^Q_`ab r3   forecast_propsc                    |D ch c]%  }|j                  d      s|j                  d      ' }}g }| D ]r  }|j                  dd      }|s||vs|j                  t        d|j                  d|      |d|j                  dd      ddd	|j                  d|       d
             t |r"t        j	                  dt        |       d       |S c c}w )zJDetect forecast props referencing players not found in recent roster data.r   r   STALE_MAPPINGr   roster_presenceevent_idr%   stale_mapping_checkr8   z+' in forecast but not in recent roster datar9   z[reconcile] z stale mapping(s) detected)r(   r;   r   r)   r*   r?   )rG   r   eroster_namesrC   proprB   s          r1   detect_stale_mappingsrP   w   s    
 7EaN_H`AEE+,aLaI xx)2.D,^- HH]D9'#xx
B7!,!$((=$"?!@@kl	 	 l3y>"22LMN' bs
   CC)N)__doc__loggingtypingr   r   r   r   r   normalizationr	   r
   modelsr   	getLoggerr)   strboolr2   rF   rP    r3   r1   <module>rZ      s    3 3 N "g( !BBB c3h(B tCH~&	B
 SMB 4.))*BJc3h( 
.>c3h(c3h( 
.r3   