o
    (Pi^                      @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ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eeef fd	d
Zdedee fddZdedeeeef  fddZde	eeef  dede	e fddZdede	e fddZde	eeef  de	e fddZd+de	eeef  de	e de	e fddZdededed ed!e	e d"ed#edeeef fd$d%Zded"ed#edeeef fd&d'Zd(d) Zed*kre  dS dS ),    N)datetime)AnyDictListOptional)load_dotenv)Config)DatabaseHandler)LeadSquaredServicereturnc                  C   s,   i } t tD ]}| rtt|| |< q| S N)dirr   isuppergetattr)cfgkey r   9/home/aiteam/pcaa-dev/dashboard-backend/sync_crm_leads.py_build_config_dict   s   r   phonec                 C   s   d dd t| p	dD }|sg S t|dkr|dd  n|}|d| |h}t|dkr?|d| d| d	| h d
d |D S )N c                 s   s    | ]	}|  r|V  qd S r   )isdigit).0chr   r   r   	<genexpr>   s    z,_normalize_phone_variants.<locals>.<genexpr>
   i+91z+910c                 S      g | ]}|r|qS r   r   )r   vr   r   r   
<listcomp>        z-_normalize_phone_variants.<locals>.<listcomp>)joinstrlenupdate)r   digitscore10variantsr   r   r   _normalize_phone_variants   s   "r*   payloadc                 C   sN   | d u rg S t | tr| S t | tr%dD ]}| |}t |tr$|  S qg S )N)r   Datalistdata)
isinstancer-   dictget)r+   r   valuer   r   r   _extract_lsq_lead_list#   s   



r3   recordkeysc                 G   s   t | tsd S |D ]}|| v r| |dvr| |  S q	|D ]!}|  D ]\}}t| t| kr@|dvr@|    S q&q d S )N)Nr   )r/   r0   r1   itemsr$   lower)r4   r5   r   
record_keyr2   r   r   r   
_lsq_field0   s   
 r9   valuesc                  G   s0   | D ]}|d u r	qt | }|r|  S qd S r   )r$   strip)r:   r2   textr   r   r   _first_present_str=   s   r=   c                 C   sn   t | tsd S tt| dd}tt| dd}ddd ||fD  p&d }tt| dd	d
d|t| ddS )N	FirstName
first_nameLastName	last_name c                 S   r   r   r   )r   partr   r   r   r!   L   r"   z%_lsq_display_name.<locals>.<listcomp>ProspectNameprospect_nameContactNamecontact_nameNamename)r/   r0   r=   r9   r#   r;   )r4   firstlast	full_namer   r   r   _lsq_display_nameG   s   
 
rM   fallback_phonec                 C   s   t | tsd S tt| ddddd}|r|S tt| ddd|p!d	}tt| d
dp+d	}t| p1d	}| d| d| }t|d S )N
ProspectIDLeadIdIdlead_id
ProspectIdPhoneMobilePhoneNumberr   EmailAddressemail|zutf-8)	r/   r0   r=   r9   rM   hashlibsha256encode	hexdigest)r4   rN   rR   r   rX   rI   digest_sourcer   r   r   _lsq_external_idT   s   
r_   dbbid
access_key
secret_keyapi_host	row_count	max_pagesc                 C   sB  t |||dd}d}d}	d}
t|D ]}|	d7 }	d|
|di}||}|ds8|d|d	p1d
|	|d  S t|d}|sC nW|D ]E}tt|ddd}t||}| j|d|t	|tt|dddtt|dd|t
|tt|dddtt|dd|t d |d7 }qEt||k r n|
t|7 }
q|d|	|dS )N-   )rb   rc   rd   timeoutr      Paging)OffsetRowCountsuccessFmessagezLeadSquared fetch failedra   rm   rn   pagessyncedr.   rT   rU   rV   leadsquared	OwnerNameOwner
owner_namerW   rX   
LeadStatusStatuslead_statusNextTaskDueDatenext_task_due_date)ra   providerexternal_lead_id	lead_nameru   rX   phone_primaryphone_variantsrx   rz   lead_payloadlast_synced_atT)ra   rm   rp   rq   )r
   rangesearch_leadsr1   r3   r=   r9   r_   upsert_crm_lead_cacherM   r*   r   utcnowr%   )r`   ra   rb   rc   rd   re   rf   servicerq   rp   offset_r+   resultleadsleadr   external_idr   r   r   _sync_bid_leadsquareda   sZ   	




r   c                 C   s   | j dd}|sddg dS g }|D ]Y}t|d}|d}|d}|d	}	|r.|s:||d
dddd qzt| ||||	||d}
||
 W q tyk } z||d
t|ddd W Y d }~qd }~ww dd|dS )Nrr   )r{   Tz(No active LeadSquared integrations found)rm   rn   resultsra   rb   rc   rd   FzMissing decrypted credentialsr   ro   )r`   ra   rb   rc   rd   re   rf   zCRM sync run complete)get_active_crm_integrationsr$   r1   appendr   	Exception)r`   re   rf   integrationsr   itemra   rb   rc   rd   resexcr   r   r   run_once   s8   


	&r   c                  C   sP  t jdd} | jdddd | jdtdd	d
 | jdtddd
 | jdtddd
 |  }t  tjtjdd t	d}t
 }t|}|  |  tdtt|jd}tdt|j}tdt|j}|jryt|||d}|d| d S |d||| 	 t }	t|||d}|d| t |	 }
td|t|
 }t| q)Nz.Sync LeadSquared CRM leads into local DB cache)descriptionz--once
store_truezRun one sync iteration and exit)actionhelpz--interval-secondsi,  z,Loop interval in seconds for continuous mode)typedefaultr   z--row-count   zRows per LeadSquared page fetchz--max-pages   zMaximum pages per bid per cyclez)%(asctime)s - %(levelname)s - %(message)s)levelformatsync_crm_leadsr   i  ri      )r`   re   rf   zCRM sync (once): %szJStarting continuous CRM sync worker interval=%ss row_count=%s max_pages=%sTzCRM sync cycle complete: %s)argparseArgumentParseradd_argumentint
parse_argsr   loggingbasicConfigINFO	getLoggerr   r	   ensure_crm_integrations_tableensure_crm_leads_cache_tablemaxminre   rf   interval_secondsoncer   infotimesleep)parserargsloggerconfigr`   safe_row_countsafe_max_pagessafe_intervaloutcomestartedelapsed	sleep_forr   r   r   main   sD   

r   __main__r   )r   rZ   r   r   r   typingr   r   r   r   dotenvr   r   r   
db_handlerr	   leadsquared_servicer
   r$   r   r*   r3   r9   r=   rM   r_   r   r   r   r   __name__r   r   r   r   <module>   sN   &"
,

">)
