o
    /^iQ                  	   @   s  d Z ddlZddl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 	d0d
edeeef ddfddZdd Zde
deeef fddZ	d0d
ede
defddZ	d0d
ede
defddZdefddZdeeef defddZdeeef defdd Zd!eeeef  d"efd#d$Zd"ed%ejd!eeeef  d&efd'd(Z deeef defd)d*Z!deeef fd+d,Z"d-eeef defd.d/Z#dS )1at  
JSON vs DB Comparison Tab

This tab provides a visual comparison interface between JSON files and MongoDB records.
Users can review differences, make import decisions, and manually apply imports.

Key features:
- Load JSON from ODF directory structure
- Compare with MongoDB records
- Visual diff display with color coding
- Manual import decisions
- No automatic writes
    N)DictAnyList)
JSONLoader)
DiffEngine)ImportPreviewEngine)UpdateEngine)DataService)ObjectIddata_serviceconfigreturnc                 C   s   |d d }t d t d |  st d dS t||d }t|d }t }t  t d t	| || t d t j
d	rRt j
d
rRt| |||| t j
drdt d t||  dS dS )z
    Render the JSON vs DB comparison tab.
    
    Args:
        mongo_service: MongoService instance
        data_service: DataService instance
        config: Application configuration dictionary
    json_sources	base_pathu   🔄 JSON vs MongoDB Comparisona  
    Compare JSON files with MongoDB records and manually import selected data.
    
    **Workflow:**
    1. Select collection and JSON source
    2. Load and compare data
    3. Review differences
    4. Make import decisions
    5. Apply selected imports
    u7   ❌ Not connected to MongoDB. Please check the sidebar.Ncollections---comparison_collectioncomparison_sourcecomparison_results)sttitlemarkdownis_connectederrorr   r   r   _init_comparison_state_render_selection_panelsession_stateget_render_load_panel_render_results_panel)mongo_servicer   r   settings_servicejson_base_pathjson_loaderdiff_enginepreview_engine r&   ./var/www/html/IGF-ODF-V3/ui/tabs/json_vs_db.pyrender_json_vs_db_tab   s2   




	
r(   c                   C   st   dt jvr	dt j_dt jvrdt j_dt jvrdt j_dt jvr$dt j_dt jvr-dt j_dt jvr8d	t j_dS dS )
z,Initialize session state for comparison tab.r   Nr   r   comparison_loadedFlast_comparison_keydata_editor_keyr   )r   r   r   r   r   r)   r*   r+   r&   r&   r&   r'   r   Z   s   





r   r#   c                 C   s  t d t d\}}|+ | }|r#t jd|ddd}|t j_nt d|j  dt j_d}W d   n1 s<w   Y  |d |d	 }d
d |	 D }|rjg }	|D ]}
|
|
|}|dkrh|	|
 qWng }	|	rt jd|	ddd}|t j_||}|d rt d|d   n|rt d| d dt j_d}W d   n1 sw   Y  | dt jj }t jj|krdt j_dt j_|t j_|r?t jjrA||t jj}|d rCt d\}}}| t d|d  W d   n1 sw   Y  | t d|d  W d   n	1 sw   Y  | | |}t d|d W d   dS 1 s8w   Y  dS dS dS dS )z
    Render collection and source selection panel.
    
    Args:
        mongo_service: MongoService instance
        json_loader: JSONLoader instance
        config: Application configuration dictionary
    u$   1️⃣ Select Source and Collection   zJSON Sourcecomparison_source_selectorz;Select JSON source directory (e.g., tokyo_2020, paris_2024))optionskeyhelpu    ⚠️ No JSON sources found in Nr   c                 S   s,   g | ]\}}| d dr| ddr|qS )enabledTallow_manual_importFr   ).0namecoll_configr&   r&   r'   
<listcomp>   s    

z+_render_selection_panel.<locals>.<listcomp>r   
Collectioncomparison_collection_selectorzGSelect a collection (only showing collections with data in this source)validation_enabled   📋 descriptionu$   ⚠️ No collections with data in ``_F	supported   z
ODF Folderfolderz
JSON Files
file_countzMongoDB Docs,)r   	subheadercolumnsget_available_sources	selectboxr   r   warningr   itemscount_files_in_sourceappendr   get_validation_infoinfor*   r   r)   get_collection_infometriccount_documents)r    r#   r   col1col2available_sourcesselected_sourcecollections_configall_collectionsavailable_collections	coll_namerB   selected_collectionvalidation_infocurrent_keyrM   col3db_countr&   r&   r'   r   o   s   
	


(

$r   r$   c                 C   s   t d t ddg\}}| t d W d   n1 s w   Y  |! t jdddd	r@t| |||| W d   dS W d   dS 1 sKw   Y  dS )
a  
    Render load and compare panel.
    
    Args:
        mongo_service: MongoService instance
        data_service: DataService instance
        json_loader: JSONLoader instance
        diff_engine: DiffEngine instance
        settings_service: SettingsService instance (optional)
    u   2️⃣ Load and Comparer@      zFClick 'Load & Compare' to analyze differences between JSON and MongoDBNu   🔄 Load & Compareload_compare_btnprimaryr/   type)r   rD   rE   rM   button_perform_comparison)r    r   r#   r$   r!   rQ   rR   r&   r&   r'   r      s*   
"r   c           '      C   sD  t jj}t jj}t dV |||}|rMtdd |D }t|dkr;t d|  t d 	 W d   dS ||vrMt 	d|
  d	| d
 d}	|rU| }	|j||	d}
W d   n1 sfw   Y  t d ||||
}W d   n1 sw   Y  d}|r||}|rt d# ddlm} ddlm} |t jj}|}||||}W d   n1 sw   Y  |t j_|t j_dt j_t j jd7  _dt jv rt j`dt jv rt j`t }|D ]}|dd | D  q|r|d d|n|}tdd |D }||}|dd}|d dd}|d dd}|dg }t  d!g d| d | d!|rJd"!|nd# d$| d%|d&  d'| d(d"!|d)  d*|rrd"!|nd+ d,|d& d-d.|d/ d-d0|d d1 d-d2|d d3 d-d4| d5| d6|d d7 d-d8|d d9 d-d:t|d-d; |rg|d }|d< dkrUt d=|d> d-d?|d@ d-dA|d< d-dB|dC  dD	 t j"dEddFU t#|dG dD ]E\}}|dH }|dI }|dJ|dKdL| }t $dM| dN| dO |D ]} t dP| dQ  dR| dS  dT| dU   q%t $dV qW d   n	1 sOw   Y  n t  dW|d> d-dB|dC  dX n|ru||rut %dY t j"dZd[dF t $d\ t &d]t|  t &d^t|
  t &d_|
rt'd`d |
d  D nda  |rt $db dcdd |d  D dde }!t (d"!|! |
rt $df dgdd |
d  D dde }"t (d"!|" t $dh t &di|d)   t &dj|  t &dk|  |r:|d) r:t $dl |d }#t &dm |d) D ]}$|#|$dn}%t &do|$ dp|%  q%|
rd|d) rdt &dq |
d }&|d) D ]}$|&|$dn}%t &do|$ dp|%  qOW d   n	1 sow   Y  |drkr|rt %dsd"!|d)  dtd"!| du ||d& k rt 	dv t )  dS )wz
    Perform the comparison between JSON and MongoDB.
    
    Args:
        mongo_service: MongoService instance
        data_service: DataService instance
        json_loader: JSONLoader instance
        diff_engine: DiffEngine instance
    zLoading data...c                 s   s    | ]}| d V  qdS )_target_collectionNr3   r4   rr&   r&   r'   	<genexpr>  s    z&_perform_comparison.<locals>.<genexpr>r^   u7   ⚠️ ERROR: Mixed collections detected in JSON data: zBThis should not happen. Each collection must be loaded separately.Nu8   ⚠️ WARNING: JSON records are marked for collection 'z' but you selected ''i  )limitzComparing records...z'Validating foreign key relationships...r   )ForeignKeyValidator)MongoServiceTnew_records_preview_dfupdate_preview_dfc                 s   s    | ]
}| d s|V  qdS )r>   N
startswithr4   kr&   r&   r'   rh   T  s    re   c                 s        | ]}| d drdV  qdS _validation_passedFr^   Nr3   rf   r&   r&   r'   rh   Z      matching_strategyprimary_onlysummaryprimary_key_matchesalternative_key_matchesalternative_keys uD   
    ✅ **Comparison Complete**
    
    - **Target Collection:** `z`
    - **JSON Source:** `z%`
    - **Expected Document Types:** , r   z
    - **Validation:** /
json_countzG records passed document type validation
    - **Matching Strategy:** `z`
    - **Primary Keys:** matching_keysz
    - **Alternative Keys:** Nonez
    - JSON Records: rC   z
    - MongoDB Records: r]   z
    - Exact Matches: exact_match_countz
    - Duplicates: duplicate_countz (Primary: z, Alternative: z)
    - New Records: new_record_countz
    - New Fields: new_field_countz
    - Total JSON Fields: z# (all nested fields flattened)
    invalid_countui   
            ❌ **Foreign Key Validation Failed**
            
            - **Total Records Checked:** total_recordsz"
            - **Valid Records:** valid_countz$
            - **Invalid Records:** z)
            - **Foreign Keys Checked:** foreign_keys_checkedur   
            
            ⚠️ Some records have invalid foreign key references. See details below.
            u"   ❌ Invalid Foreign Key References)expandedinvalidrecorderrorscodeidRecord #z**z. Record: `z`**u   ❌ Field `fieldz` = `valuez`: r   r   uc   
            ✅ **Foreign Key Validation Passed**
            
            - **Records Checked:** zL
            
            All foreign key references are valid!
            uB   ℹ️ Foreign key validation is configured but was not performed.u   🔍 Debug InformationFz### Data Loading DetailszJSON records loaded: zMongoDB records loaded: zMongoDB records are flattened: c                 s   s    | ]}d |v V  qdS ).Nr&   rq   r&   r&   r'   rh     s    N/Az+### Sample JSON Record Keys (first record):c                 S      g | ]	}| d s|qS r>   ro   rq   r&   r&   r'   r7         z'_perform_comparison.<locals>.<listcomp>   z.### Sample MongoDB Record Keys (first record):c                 S   r   r   ro   rq   r&   r&   r'   r7     r   z### Business Key MatchingzPrimary keys configured: zAlternative keys configured: zMatching strategy: z### Sample Business Key ValueszFrom first JSON record:z	NOT FOUNDz  : zFrom first MongoDB record:primary_or_alternativeu\   💡 **Multi-Key Matching Enabled:**
        - System first tries to match by primary keys: z0
        - If no match, tries alternative keys: zj
        - This allows matching athletes across different competitions even if their codes differ
        uc   ⚠️ Note: Some files were skipped due to document type mismatch. Check console logs for details.)*r   r   r   r   spinnerload_collection_from_sourcesetlenr   rH   popget_record_limitload_flattened_recordscompare_collectionsget_foreign_keysservices.foreign_key_validatorrk   services.mongorl   r    validate_foreign_keysr   fk_validation_resultsr)   r+   rm   rn   updatekeysr   sumget_expected_document_typessuccessjoinexpander	enumerater   rM   textanyr   rerun)'r    r   r#   r$   r!   collection_namesource_namejson_recordstarget_collectionsrecord_limit
db_recordsresultsr   foreign_keysrk   rl   fk_validatorall_records_to_validateall_json_fieldsr   target_collectionvalidation_passed_countexpected_typesrw   primary_matchesalt_matchesr|   
fk_summaryidxitemr   	record_idr   sample_json_keyssample_db_keyssample_jsonr/   r   	sample_dbr&   r&   r'   rd      sV  
	



	











,

0





%

rd   r%   c                 C   sT  t jj}t d t d\}}}}| t jd|d d dd W d   n1 s+w   Y  | t jd	|d d
 |d d
 ddd W d   n1 sOw   Y  | t jd|d d |d d ddd W d   n1 ssw   Y  | t jd|d d dd W d   n1 sw   Y  t d t d|d d  dd|d d
  dd|d d  dd|d d  dg\}}}	}
| t||  W d   n1 sw   Y  | t	|| | W d   n1 sw   Y  |	 t
|| | W d   n	1 sw   Y  |
 t| W d   dS 1 s#w   Y  dS )z
    Render comparison results with tabs.
    
    Args:
        preview_engine: ImportPreviewEngine instance
        mongo_service: MongoService instance
    u   3️⃣ Review Differences   zExact Matchesry   r   zRecords that are identicalr0   N
Duplicatesr   normalz8Records with matching business keys but different values)deltadelta_colorr0   zNew Recordsr   zRecords not found in MongoDB
New Fieldsr   zFields in JSON not in MongoDBr   u   ✅ Exact Matches ()u   ⚠️ Duplicates (u   🆕 New Records (u   📋 New Fields ()r   r   r   rD   rE   rO   r   tabs_render_exact_matches_tab_render_duplicates_tab_render_new_records_tab_render_new_fields_tab)r%   r    r   rQ   rR   r\   col4tab1tab2tab3tab4r&   r&   r'   r     sl   



	

	


$r   r   c                 C   s   | d }|st d dS tdd |D }t dt| d |t|kr,t d t d	 ||d
}|jsh|jdd |j	D dd}t dt| dt|j	 d t d t j
|dddd dS dS )z%Render exact matches tab (read-only).exact_matchesu   ℹ️ No exact matches foundNc                 s   rs   rt   r3   rf   r&   r&   r'   rh   #  rv   z,_render_exact_matches_tab.<locals>.<genexpr>u   ✅ z* records are identical in JSON and MongoDBu/   ✅ All records passed document type validationu   
    These records are already in MongoDB and match exactly.
    **No action needed.**
    
    🟠 **Orange background** = These values exist in MongoDB (identical to JSON)
    exactc                 S   s   g | ]	}| d r|qS r   ro   r4   cr&   r&   r'   r7   6  r   z-_render_exact_matches_tab.<locals>.<listcomp>ignore)rE   r      📊 Displaying  records with z% fields (all nested fields flattened)u<   **🟠 These values are identical in both JSON and MongoDB**T  use_container_width
hide_indexheight)r   rM   r   r   r   r   build_preview_dataframeemptydroprE   	dataframe)r   r%   r   validated_countdf
display_dfr&   r&   r'   r     s*   


"

r   c                    sT  | d }|st d dS tdd |D }tdd |D }tdd |D }t dt| d	 |t|kr?t d
 nt d| dt| d |dkrpt d| dd| d  d| dd| dg  d	 nt dd| d  d t d t d t|D ]R\}}|dd}	|dd}
|	dkrd nd!}|	dkrd"nd#}t 	| d$|d%  d&| d'|
  t 
d(|  t 
d)|
  W d   n1 sw   Y  qt d* ||  js( fd+d,}t d-  jj|d%d.}t d/t  d0 t j|d1d1d2d3 t d4 t d* t|| d5 | dS dS )6z+Render duplicates tab with comparison view.
duplicatesu   ℹ️ No duplicates foundNc                 s   $    | ]}|d   ddrdV  qdS json_recordru   Fr^   Nr3   r4   dr&   r&   r'   rh   Q     " z)_render_duplicates_tab.<locals>.<genexpr>c                 s   "    | ]}| d dkrdV  qdS )match_methodprimary_keyr^   Nr3   r   r&   r&   r'   rh   T       c                 s   r   )r   alternative_keyr^   Nr3   r   r&   r&   r'   rh   U  r      ⚠️ z potential duplicate(s) foundu9   ✅ All duplicate records passed document type validation   ⚠️ Only r   z duplicates passed validationr   u"   🔍 **Match Methods:**
        - z matched by primary keys: r~   r   z
        - z matched by alternative keys: r|   u   
        
        💡 Alternative key matches allow finding the same athlete across different competitions 
        even when their athlete code differs.
        z1
        These records match by business keys: **z**
        u9  
    **Update Workflow:**
    1. Review field-by-field comparison below
    2. Select which fields to update (✅ Update or ❌ Skip)
    3. Apply updates to MongoDB
    
    💡 **Use Case:** When athlete info changes (name, birthdate, nationality), 
    you can selectively update only the changed fields.
    z### Duplicate Recordsr   unknownmatching_keyr   r   u   🔑u   🔍zPrimary KeyzAlternative Keyz Duplicate #r^   z - Matched by r   zMatch Method: zMatching Values: r   c                    s   g }t  jD ]U\}}|dkr|d q|dkrC| d dkr%|d q| d dkr1|d q| d dkr=|d	 q|d q|d
krM|d q|dkrW|d q|d q|S )Nr   r}   statusnewz,background-color: #90EE90; font-weight: bold	differentz,background-color: #FFD700; font-weight: boldmissing_in_jsonz,background-color: #FFB6C1; font-weight: bold
json_valuez9background-color: #E3F2FD; border-left: 3px solid #2196F3db_valuez9background-color: #FFF3E0; border-left: 3px solid #FF9800)r   rE   rK   )rowstylesr   colcomp_dfr&   r'   highlight_comparison  s$   z4_render_duplicates_tab.<locals>.highlight_comparisonz### Field-by-Field Comparison)axisr   z- field comparisons with full nested structureTr   r   u  
        **Color Legend:**
        - 🟢 **Green** = New field in JSON (not in MongoDB)
        - 🟡 **Yellow** = Different values between JSON and MongoDB
        - 🔴 **Pink** = Field exists in MongoDB but missing in JSON
        - 🔵 **Blue background** = Value from JSON file
        - 🟠 **Orange background** = Value from MongoDB
        - ⚪ **White** = Matching values
        r   )r   rM   r   rH   r   r   r   r   r   r   r   $build_duplicate_comparison_dataframer   styleapplyr   _render_update_controls)r   r%   r    r   r   r   r   r   dupr   r   
match_iconmatch_labelr  	styled_dfr&   r
  r'   r   D  sr   



&





r   r   r   c                 C   s  t d t d t }dt jvr|| t j_t jj}|jr't d dS t g d\}}}}}	| t j	ddd	d
rL|j
|dgdt j_t   W d   n1 sVw   Y  | t j	dddd
rt|j
|dgdt j_t   W d   n1 s~w   Y  | t j	dddd
r||t j_t   W d   n1 sw   Y  |	 t j	dddd
r|| t j_t   W d   n1 sw   Y  t d ||}
t d\}}}}| t d|
d  W d   n1 sw   Y  | t d|
d  W d   n	1 sw   Y  | t d|
d  W d   n	1 s+w   Y  | t d|
d   W d   n	1 sFw   Y  t d t d! t d" t j|d#d#d$d%t jjd&d#d'd(t jjd)d#d'd(t jjd*d#d+d(t jjd,d#d'd(t jjd-d#d+d(t jjd.d#d+d(t jjd/d0d1gd#d2d'd3d4d5t jj d6}|t j_|
d d7kr t d t d8|
d  d9|
d  d: t d;d<g\}}|" t j	d=d>d?d@rt||| || W d   dS W d   dS 1 sw   Y  dS dS )Az
    Render update controls for selective field updates.
    
    Args:
        duplicates: List of duplicate records
        collection_name: Name of the collection
        mongo_service: MongoService instance
    u   🔄 Selective Field Updatesu   
    💡 **How it works:**
    - Select which fields you want to update in MongoDB
    - New fields are selected by default
    - Different fields require your decision
    - Matching fields are skipped by default
    rn   u   ℹ️ No fields to updateN)r,   r^   r^   r^   r^   u   ✅ Update New Fieldsupdate_new_fieldszMark all new fields for update)r/   r0   r  )status_filteru   ✅ Update Differentupdate_different_fieldsz$Mark all different fields for updater  u   ❌ Skip Allskip_all_updateszSkip all updates
   🔄 Resetreset_update_decisionszReset to defaultsr   r   zRecords to Updaterecords_to_updatezFields to Updatefields_to_updater   
new_fieldszDifferent Fieldsdifferent_fieldsz### Select Fields to UpdateuR  
    **Color Legend:**
    - 🟢 **Green** (new) - Field exists in JSON but not in MongoDB
    - 🟡 **Gold** (different) - Field value differs between JSON and MongoDB
    - 🟣 **Pink** (missing_in_json) - Field exists in MongoDB but not in JSON
    - 🔵 **Light Blue** - JSON value
    - 🟠 **Light Orange** - MongoDB value
    Tfixedr   r   small)disabledwidthzDB IDz
Field NamemediumStatusz
JSON ValuezMongoDB ValueActionskipr   z#Choose whether to update this fieldr.   requiredr0   r#  )_record_index_db_idr   r  r  r  _update_decisionupdate_preview_editor_r   r   num_rowsr   column_configr/   r   u   ⚠️ Ready to update z record(s) with z	 field(s)r@   r^   u   🚀 Apply Updatesapply_updates_btnr`   ra   )r   rD   rM   r   r   build_update_preview_dataframern   r   rE   rc   mark_all_for_updater   mark_all_for_skipr   get_update_summaryrO   data_editorr0  NumberColumn
TextColumnSelectboxColumnr+   rH   _apply_field_updates)r   r   r    update_enginer   rQ   rR   r\   r   col5ry   	edited_dfr&   r&   r'   r    s   

	






	'1
 $r  
preview_dfr;  c                 C   s  t d ||}t d|d  d|  d|d  d|d  d	|d
  d t d\}}|
 t jdddddr4|||}|sRt d 	 W d   dS || }	|	r/zt 	dt
| dO d}
g }|D ]@}zdt|d d i}|	||d }|jdkr|
d7 }
W qm ty } z|d|d  dt|  W Y d}~qmd}~ww W d   n1 sw   Y  |
dkrt d|
 d|  d  |rt d!t
| d" |dd# D ]
}t d$|  qdt j_dt j_d%t j_t d& nt d' |r|D ]}t | qW n" ty. } zt d(t|  W Y d}~n
d}~ww t d) W d   n	1 s?w   Y  |# t jd*d+dd,rat d- t   W d   dS W d   dS 1 smw   Y  dS ).a2  
    Apply selected field updates to MongoDB.
    
    Args:
        collection_name: Name of collection
        preview_df: Preview DataFrame with update decisions
        duplicates: Original duplicate records
        update_engine: UpdateEngine instance
        mongo_service: MongoService instance
    z### Confirm Updatesu&   
    ⚠️ **You are about to update r  z record(s) in z+**
    
    This action will:
    - Update r  z field(s) in MongoDB
    - Preserve all other fields unchanged
    - Cannot be undone automatically
    
    **Fields to update:**
    - New fields: r  z
    - Different fields: r  z
    r,   u   ✅ Confirm Updatesconfirm_updates_btnr`   Tr/   rb   r   u#   ❌ No update operations to performNz	Updating z record(s)...r   _idfilterr   r^   zRecord record_indexr   u   ✅ Successfully updated z record(s) in collection: `r=   r   z update(s) failed:   z  - F1   💡 Reload the comparison to see updated resultsu   ⚠️ No records were updatedu   ❌ Failed to update: u   ❌ Collection not found
   ❌ Cancelcancel_updates_btnr/   r   zUpdates cancelled)r   r   r5  rH   rE   rc   prepare_update_operationsr   get_collectionr   r   r
   
update_onemodified_count	ExceptionrK   strr   r   r   rn   r   r)   rM   r   )r   r>  r   r;  r    ry   rQ   rR   
operations
collectionupdated_countr   opfilter_dictresulter   r&   r&   r'   r:  m  s   

	




*
 
;

$r:  c              	   C   s  | d }|st d dS |r|d d ddnd}tdd	 |D }t d
t| d| d |t|krBt d| d nt d| dt| d t d dt jvrb|	|dt j_
t jj
}|jrkdS t g d\}}}	}
| t jddddr||t j_
t   W d   n1 sw   Y  |	 t jdddr||t j_
t   W d   n1 sw   Y  |
 t jdddr|	|dt j_
t   W d   n1 sw   Y  t d d d! |jD }t d"t| d#t| d$ t jjd%g d&dd'd(d)t jjd*dd+d(d,d-}|jD ]:}|d.sU|| j}|d/v r:t jj|d0d1||< q|d2krKt jj|d3d1||< qt jj|d4d1||< qt j|ddd5d6|d7t jj d8}|t j_
||}t d9 t d:\}}}	| t d;t|d<  W d   n	1 sw   Y  | t d=t|d>  W d   n	1 sw   Y  |	 t d?t|d@  W d   n	1 sw   Y  t|d< dkrAt d t dAt|d<  dB dCt jvrdt j_t d:dDg\}}|" t jdEdFddGr | dH |d< ||dIt j_t   W d   n	1 s+w   Y  t jjdurCtt jj|| dS dS dS )Jz,Render new records tab with import controls.new_recordsu   ℹ️ No new records foundNr   r   re   r   c                 s   r   r   r3   rf   r&   r&   r'   rh     r   z*_render_new_records_tab.<locals>.<genexpr>u   🆕 z0 new record(s) ready for import to collection: `r=   u   ✅ All z( records passed document type validationr   r   z records passed validationu  
    These records are not in MongoDB. You can:
    - Review and edit the data
    - Select records to import
    - Apply imports manually
    
    🔵 **Blue background** = Values from JSON files (not yet in MongoDB)
    ✅ **Validated** = Document type matches target collection
    rm   r  )r,   r^   r^   r^   u   ✅ Import Selected Recordsr`   T)rb   r   u   ❌ Mark All Skipmark_all_skip)r/   r  reset_decisionsr   c                 S   r   r   ro   r   r&   r&   r'   r7     r   z+_render_new_records_tab.<locals>.<listcomp>r   r   zS data fields (all nested fields flattened). Scroll horizontally to see all columns.zImport?)pendingimportr'  z$Select whether to import this recordr!  r(  Rowz	Row index)r"  r0   r#  )_import_decision
_row_indexr>   )int64int32float64float32zNumeric value from JSON filer   boolzBoolean value from JSON filezValue from JSON filer   i  new_records_editor_r.  z### Import Summaryr@   z	To ImportrZ  zTo Skipr'  PendingrY  u   ⚠️ Ready to import z
 record(s)pending_importr^   u   🚀 Apply Importsapply_imports_btnra   r   )r   import_indicesrV  r>  )r   rM   r   r   r   r   rH   r   r   r   rm   r   rE   rc   mark_all_for_importr   r4  r0  r9  r7  rp   dtypeCheckboxColumnr8  r6  r+   extract_import_decisionsrO   re  _show_import_confirmation)r   r%   r    rV  r   validated_recordsr   rQ   rR   r\   r   data_columnsr0  r	  ri  r=  	decisionsr&   r&   r'   r     s   



 








r   c                 C   sb   | d }|st d dS t dt| d t d |D ]
}t d|  qt d dS )	zRender new fields tab.r  u   ℹ️ No new fields detectedNr;   z new field(s) found in JSONz
    These fields exist in JSON but not in MongoDB.
    
    **Recommendation:** Use the Schema Manager to add these fields before importing.
    u   • uH   💡 Go to the collection tab and use Schema Manager to add these fields)r   rM   rH   r   r   r   )r   r  r   r&   r&   r'   r     s   

r   pending_datac                 C   s  | d }| d }| d }| d }t d t dt| d| d t d	\}}| t jd
ddddrg }	|D ]}
t|
trNd|
v rN|	|
d  q;|	|
 q;|	r^|	d 	d|n|}|j
||	|dd}t|dkr}t d 	 W d   dS ||}|du rt d| d 	 W d   dS zMt dt| d| d ||}W d   n1 sw   Y  t dt|j d| d dt j_dt j_dt j_dt j_t d t   W n ty } zt dt|  W Y d}~nd}~ww W d   n	1 sw   Y  |' t jd d!dd"r4dt j_t d# t   W d   dS W d   dS 1 s@w   Y  dS )$a  
    Show import confirmation dialog and execute import.
    
    Args:
        pending_data: Dictionary with collection_name, import_indices, new_records, preview_df
        preview_engine: ImportPreviewEngine instance
        mongo_service: MongoService instance
    r   rg  rV  r>  u   ### ⚠️ Confirm Importz
    **You are about to import z record(s) to `zp`**
    
    This action will:
    - Insert new documents into MongoDB
    - Cannot be undone automatically
    r,   u   ✅ Confirm Importconfirm_import_btnr`   Tr@  r   r   re   )	unflattenu#   ❌ No records prepared for import!Nu   ❌ Collection `z%` not found or MongoDB not connected!z
Importing z records to z...u   ✅ Successfully imported z records to collection: `r=   FrE  u   ❌ Failed to import: rF  cancel_import_btnrH  zImport cancelled)r   r   r   r   rE   rc   
isinstancedictrK   r   prepare_records_for_importrJ  r   insert_manyr   inserted_idsr   rm   r   r)   re  rM   balloonsrM  rN  r   )rp  r%   r    r   rg  original_recordsr>  rQ   rR   r   recr   records_to_importrP  rT  rU  r&   r&   r'   rl    s   



 &
 8

$rl  )N)$__doc__	streamlitr   pandaspdtypingr   r   r   services.json_loaderr   services.diff_enginer   services.import_preview_enginer   services.update_enginer   services.data_servicer	   bsonr
   rN  r(   r   r   r   rd   r   r   r   r  	DataFramer:  r   r   rl  r&   r&   r&   r'   <module>   s    

@f
,
 ^F*

 
 (
j

 4
