
    hi=                         d Z ddlZddlZddl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  ej,                  e      Z G d d      Z e       Zy)uv   
Gestionnaire de conversations WhatsApp - Version Améliorée
Avec détection d'intentions et validation intelligente
    N)datetime)DictOptionalList)Session)UserService)cv_parser_service)linkedin_service)twilio_service)job_offer_service)
UserCreatec                      e Zd ZdZh dZh dZd ZdedefdZ	dede
eef   fd	Zdedefd
Zdedee   fdZ	 	 	 d0dededededededefdZdedefdZdedefdZdedefdZdedefdZdededededef
dZdededefdZdededefdZdededefdZd1dededefdZdededefdZdededefdZdededefdZd1dedededededefd Zdededefd!Zdedededededefd"Z dededededef
d#Z!ded$edefd%Z"d1dedefd&Z#d2d'edefd(Z$dedefd)Z%defd*Z&defd+Z'd,edefd-Z(ded,edefd.Z)ded,edefd/Z*y)3ConversationHandlerz(Gestionnaire principal des conversations>      noté   génialvas-yd'accordgohiokheyouitopyesbiencoolokayvasyallezhellomercisalutsupercoucounickelbonjourbonsoircomprisdaccordentenduparfaitcontinue>   nonannonpasnopeaucunaucunejamaisc                 "    t               | _        y N)r   user_serviceselfs    I/home/www/therecruiter.miabetepe.com/app/services/conversation_handler.py__init__zConversationHandler.__init__%   s    'M    textreturnc                     |sy|j                         j                         }t        j                  dd|      }|sy|j	                         }t        |      dk(  r|d    j                  v ryt         fd|D              ryy)u1   Vérifie si le message est juste un acquiescementTz[^\w\s]    r   c              3   :   K   | ]  }|j                   v   y wr6   )ACKNOWLEDGMENT_WORDS).0wordr9   s     r:   	<genexpr>z=ConversationHandler.is_acknowledgment_only.<locals>.<genexpr><   s     CTtt000Cs   F)lowerstripresubsplitlenrC   all)r9   r=   
text_cleanwordss   `   r:   is_acknowledgment_onlyz*ConversationHandler.is_acknowledgment_only(   s~    ZZ\'')
 VVJJ7
    "u:?uQx4+D+DD CUCCr<   namec                 X   |rt        |j                               dk  ry|j                         }| j                  |      ryt        |      dkD  ryt        j                  d|      sy|j                         ry|j                         }t        |      dk  ry	t        d
 |D              ryy)u,   Valide un nom avec des règles plus strictes   )Fu.   Le nom est trop court (minimum 2 caractères).)Fz>Ce n'est pas un nom valide. Veuillez entrer votre nom complet.d   )Fu/   Le nom est trop long (maximum 100 caractères).u   [a-zA-ZÀ-ÿ])Fz)Le nom doit contenir au moins une lettre.)Fu9   Un nom ne peut pas être composé uniquement de chiffres.)Fu9   Veuillez entrer votre *prénom ET nom* (ex: Jean Dupont).c              3   8   K   | ]  }t        |      d k    yw)rS   N)rL   )rD   rE   s     r:   rF   z4ConversationHandler.is_valid_name.<locals>.<genexpr>^   s     /s4y1}/s   )Fu7   Chaque partie du nom doit faire au moins 2 caractères.)Tr@   )rL   rH   rP   rI   searchisdigitrK   any)r9   rQ   rO   s      r:   is_valid_namez!ConversationHandler.is_valid_nameA   s    s4::<(1,Jzz| &&t,Z t9s?K yy)40E <<>U 

u:>U ///Sr<   c                 t    |sy|j                         j                         }| j                  |      ryd|vryy)u>   Vérifie si le texte ressemble à une intention d'email valideF@T)rH   rG   rP   )r9   r=   s     r:   is_valid_email_intentz)ConversationHandler.is_valid_email_intentc   s>    zz|!!# &&t, d?r<   c                     |sy|j                         j                         }t        j                  d|      }|r|d   }|dv r|S d|v rd|v ryd|v rd|v ry	d|v rd|v ry
|dv r|S y)z)Extrait le choix (1, 2 ou 3) d'un messageNz\d+r   )123cvlinkedinr`   	seulementr^   r_   )rH   rG   rI   findall)r9   r=   numberschoices       r:   extract_choicez"ConversationHandler.extract_choicet   s    zz|!!# **VT*QZF( 4<J$.T\kT14K4$7_$Kr<   Ndbfrom_numbermessage_body	num_media	media_urlmedia_content_typec                 N   	 |j                  dd      }t        j                  d| d|        | j                  j	                  ||      }|s(t        |      }	| j                  j                  ||	      }|r|j                         j                  d      j                         j                         }
|
dv r| j                  ||      S |
dv r| j                  |      S |
d	v r| j                         S |
d
v r| j                  ||      S |
dv r| j                  ||      S |
dv r| j                  ||      S |
dv r| j                  ||      S |
dv r9|j                   j#                  d      r| j                  j%                  ||d       y|
j#                  d      r&t'        |
      dkD  r|
dd }| j)                  |||      S |
j#                  d      r&t'        |
      dkD  r|
dd }| j+                  |||      S |
j#                  d      r=t'        |
      dkD  r/|
j#                  d      s|
dd }h d}||vr| j-                  |      S |j                   }|dk(  r| j/                  |||      S |dk(  r| j1                  |||      S |dk(  r| j3                  |||      S |dk(  r| j5                  |||      S |dk(  r| j7                  ||||||      S |d k(  r| j9                  |||      S |d!k(  r| j;                  ||||||      S |dk(  r| j=                  ||      S |d"k(  r| j?                  |||||      S |d#k(  r| jA                  |||      S |d$k(  r| jC                  |||      S |d%k(  r| jE                  |||      S y&# tF        $ r$}t        jI                  d'| d()       Y d}~y*d}~ww xY w)+zTraite un message WhatsAppz	whatsapp:r@   u   📨 Message de z: )phone_number*_~`)z/resetresetrecommencer)z/statusstatusstatut)z/aideaidehelpz/help)z/cvra   majcvupdatecv)z	/linkedinrb   majlinkedinupdatelinkedin)z/emailmajemailupdateemail)z/nommajnom
updatename)/annulerannulercancel	updating_	completedu>   🔙 Action annulée.

Tapez */status* pour voir votre profil.z/status-job-   Nz/submit-   /rA   z//>	   ra   nomru   rv   emailrq   rs   r   rb   initialawaiting_nameawaiting_emailawaiting_choiceawaiting_cvawaiting_linkedinawaiting_remainingupdating_cvupdating_linkedinupdating_emailupdating_namez&Erreur. Tapez /reset pour recommencer.u   ❌ Erreur process_message: Texc_infou*   ❌ Une erreur est survenue. Tapez /reset.)%replaceloggerinfor7   get_user_by_phoner   create_userrH   rG   handle_resethandle_statushandle_helphandle_update_cvhandle_update_linkedinhandle_update_emailhandle_update_nameconversation_state
startswithupdate_staterL   handle_application_statushandle_apply_to_offerhandle_view_offerhandle_initialhandle_namehandle_emailhandle_choice	handle_cvhandle_linkedinhandle_remaininghandle_completedhandle_cv_update_uploadhandle_linkedin_update_inputhandle_email_update_inputhandle_name_update_input	Exceptionerror)r9   rh   ri   rj   rk   rl   rm   ro   user	user_datacmdtagknown_commandsstatees                  r:   process_messagez#ConversationHandler.process_message   s   b	@&..{B?LKK*<.<.IJ $$66r<HD&LA	((44RC  #((*008>>@FFH<<,,R6699--d33<<++-- <<00T::TT66r4@@??33B==::222t<< ;;..99+F))66r4M +
 >>.1c#hmbc(C99"dCHH >>*-#c(Q,ab'C55b$DD >>#&3s8a<t@Tab'C%uN.0#55c:: ++E	!**2t\BB/)''D,??**((T<@@++))"dLAA-'~~b$	9FXZfgg--++BlCC..,,R|YPY[mnn+%,,T<@@-'33BiTfgg--88T<PP**55b$MM/)44R|LL? 	@LL7s;dLK?	@s   CM7 	M7 M7 2M7 M7 M7 4M7 
<M7 6M7 >6M7 5AM7 #M7 'M7 ?M7 M7 /M7 
M7 "M7 =M7 M7 .M7 M7 M7 7	N$ NN$c                     |j                   dvry| j                  j                  ||d       |j                  xr |j                  i k7  }|ryy)u"   Commande pour mettre à jour le CVr   r   g   ⚠️ Vous êtes déjà en cours d'inscription.

Terminez d'abord votre inscription ou tapez */reset*.r   u   📄 *Mise à jour du CV*

Vous avez déjà un CV enregistré.

Envoyez votre *nouveau CV en PDF* pour le remplacer.

_Tapez /annuler pour revenir_uz   📄 *Ajout d'un CV*

Vous n'avez pas encore de CV enregistré.

Envoyez votre *CV en PDF*.

_Tapez /annuler pour revenir_)r   r7   r   cv_data)r9   rh   r   has_cvs       r:   r   z$ConversationHandler.handle_update_cv   sT    ""*BB9 	&&r4?4$,,""4!!r<   c                     |j                   dvry| j                  j                  ||d       |j                  xr |j                  i k7  }|r"|j                  j	                  dd      }d| dS y)	u%   Commande pour mettre à jour LinkedInr   r   r   urlN/Au7   🔗 *Mise à jour du profil LinkedIn*

Profil actuel: u   

Envoyez votre *nouvelle URL LinkedIn*.

💡 *En fournissant votre lien, vous nous autorisez à récupérer automatiquement vos informations professionnelles publiques.*

_Tapez /annuler pour revenir_uW  🔗 *Ajout d'un profil LinkedIn*

Vous n'avez pas encore de profil LinkedIn enregistré.

Envoyez l'*URL de votre profil LinkedIn*.

💡 *En fournissant votre lien, vous nous autorisez à récupérer automatiquement vos informations professionnelles publiques.*

_Exemple: https://linkedin.com/in/votre-profil_

_Tapez /annuler pour revenir_)r   r7   r   linkedin_profileget)r9   rh   r   has_linkedincurrent_urls        r:   r   z*ConversationHandler.handle_update_linkedin  s    ""*BB9 	&&r41DE,,L1F1F"1L//33E5AK} ! !
!r<   c                     |j                   dvry|j                  sy| j                  j                  ||d       d|j                   dS )u$   Commande pour mettre à jour l'emailr   r   uY   ⚠️ Vous n'avez pas encore d'email enregistré.

Complétez d'abord votre inscription.r   u.   📧 *Mise à jour de l'email*

Email actuel: z>

Envoyez votre *nouvel email*.

_Tapez /annuler pour revenir_)r   r   r7   r   r9   rh   r   s      r:   r   z'ConversationHandler.handle_update_email=  s\    ""*BB9 zz) 	&&r41ABzzl ! 	!r<   c                     |j                   dvry|j                  sy| j                  j                  ||d       d|j                   dS )u#   Commande pour mettre à jour le nomr   r   uX   ⚠️ Vous n'avez pas encore de nom enregistré.

Complétez d'abord votre inscription.r   u(   👤 *Mise à jour du nom*

Nom actuel: zE

Envoyez votre *nouveau nom complet*.

_Tapez /annuler pour revenir_)r   	full_namer7   r   r   s      r:   r   z&ConversationHandler.handle_update_nameS  s\    ""*BB9 ~~) 	&&r4A^^ ! 	!r<   c                 :   	 |dk(  s|syt        j                  |      \  }}t        j                  |t	        |            \  }}	|sd|	 dS t        j
                  |      }
d|t        j                         j                         t        j                         j                         |
d}| j                  j                  |||       |
j                  dd      j                         }|r)|j                  s| j                  j                  |||       | j                  j                  ||d	       t	        |
j                  d
g             }t	        |
j                  dg             }d| d| dS # t         $ r$}t"        j%                  d| d       Y d}~yd}~ww xY w)zTraite l'upload du nouveau CVr   ub   ⚠️ Aucun fichier reçu.

Envoyez votre CV en PDF (bouton 📎).

_Tapez /annuler pour revenir_   ❌ z7

Envoyez un PDF valide.

_Tapez /annuler pour revenir_cv.pdf)	file_namefile_urluploaded_at
updated_atparsed_contentlocationr@   r   skills
experienceu7   ✅ *CV mis à jour avec succès !*

📊 *Analyse:*
-     compétences détectées
- ui    expériences professionnelles

Votre profil a été actualisé.

Tapez */status* pour voir votre profil.u   ❌ Erreur mise à jour CV: Tr   NuD   ❌ Erreur lors de l'analyse du CV.

Réessayez ou tapez */annuler*.)r   download_mediar	   validate_cv_filerL   	parse_pdfr   utcnow	isoformatr7   update_cv_datar   rH   r   update_locationr   r   r   r   )r9   rh   r   rk   rl   rm   media_contentcontent_typeis_validmsgparsed_datar   cv_locationskills_count	exp_countr   s                   r:   r   z+ConversationHandler.handle_cv_update_uploadk  s   6	#A~Y! +9*G*G	*R'M<->>|SQ^M_`MHcu % ! ! ,55mDK &%'0::<&oo/99;"-G ,,Rw? &//*b9??AK4==!!11"dKH**2t[A{x<=LKOOL"=>I . + (	+ +  	#LL7s;dLK#	#s$   E- AE- D E- -	F6FFc                 f   |r|j                         nd}|j                         dv r| j                  j                  ||d       yt        j                  d|        t        j                  |      \  }}}|sd| dS | j                  j                  |||       |j                  di       j                  d	d      j                         }|r| j                  j                  |||       | j                  j                  ||d       t        |j                  di       j                  d
            }	|	rj|j                  di       }
|
j                  d
d      }t        |
j                  dg             }t        |
j                  dg             }d|xs d d| d| dS d|j                  dd       dS )u)   Traite la mise à jour du profil LinkedInr@   r   r   r   r   D   🔙 Mise à jour annulée.

Tapez */status* pour voir votre profil.u   🔍 Mise à jour LinkedIn:    ⚠️ zO

*Format:* https://linkedin.com/in/votre-profil

_Tapez /annuler pour revenir_scraped_datar   headliner   r   uM   ✅ *Profil LinkedIn mis à jour !*

📊 *Données récupérées:*
- Poste:    Non spécifié   
- Expériences:    
- Compétences: uK   

Votre profil a été actualisé.

Tapez */status* pour voir votre profil.u*   ✅ *Profil LinkedIn mis à jour !*

URL: r   )rH   rG   r7   r   r   r   r
   validate_and_scrapeupdate_linkedinr   r   boolrL   )r9   rh   r   rj   
input_textsuccessr   linkedin_datalinkedin_locationhas_scraped_datar   r   r   r   s                 r:   r   z0ConversationHandler.handle_linkedin_update_input  s   -9\'')r
!BB**2t[A+ 	2:,?@&6&J&J:&V#mse $ ! ! 	))"dMB *--nbAEEjRTU[[]--b$8IJ&&r4= 1 1." E I I* UV(,,^R@L#''
B7HL,,\2>?I|//"=>L
 
&&	' (  (	+ 	+r"# $(+ +r<   c                 z   |r|j                         nd}|j                         dv r| j                  j                  ||d       y|j                         }d}t	        j
                  ||      sy|j                  }| j                  j                  |||       | j                  j                  ||d       d| d| d	S )
u!   Traite la mise à jour de l'emailr@   r   r   r   0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$uU   ⚠️ Email invalide.

Format: nom.prenom@exemple.com

_Tapez /annuler pour revenir_u#   ✅ *Email mis à jour !*

Ancien: 

Nouveau: )

Tapez */status* pour voir votre profil.)rH   rG   r7   r   rI   matchr   update_email)r9   rh   r   rj   r   r   email_pattern	old_emails           r:   r   z-ConversationHandler.handle_email_update_input  s    -9\'')r
!BB**2t[A+   "Kxxu-! JJ	&&r47&&r4=		 

 (+ 	+r<   c                 d   |r|j                         nd}|j                         dv r| j                  j                  ||d       y|}| j	                  |      \  }}|sd| dS |j
                  }| j                  j                  |||       | j                  j                  ||d       d| d| d	S )
u   Traite la mise à jour du nomr@   r   r   r   r   z

_Tapez /annuler pour revenir_u!   ✅ *Nom mis à jour !*

Ancien: r   r   )rH   rG   r7   r   rY   r   update_name)	r9   rh   r   rj   r   rQ   r   	error_msgold_names	            r:   r   z,ConversationHandler.handle_name_update_input  s    -9\'')r
!BB**2t[A+ "006)yk * ! ! >>%%b$5&&r4=		
 

 (+ 	+r<   c                     |r/| j                  |      r| j                  j                  ||d       y| j                  |||      S )u,   Message de bienvenue - gère les salutationsr   u   👋 Bienvenue sur notre plateforme de recrutement KARABA AI!

Je vais vous aider à enregistrer votre profil.

📝 Pour commencer, veuillez me donner votre *nom complet* (prénom et nom).

_Exemple: Jean Dupont_

_Tapez /aide pour voir les commandes._)rP   r7   r   r   )r9   rh   r   rj   s       r:   r   z"ConversationHandler.handle_initial  sH     D77E**2t_E* D,77r<   c                     |r|j                         nd}| j                  |      \  }}|sd| dS | j                  j                  |||       | j                  j	                  ||d       d| dS )z,Collecte du nom avec validation intelligenter@   r   uO   

*Exemple de nom valide:* Jean Dupont

Veuillez entrer votre *prénom ET nom*.r   zMerci *uU   * ! 📧

Maintenant, votre *email professionnel*.

_Exemple: nom.prenom@exemple.com_)rH   rY   r7   r  r   )r9   rh   r   rj   rQ   r   r  s          r:   r   zConversationHandler.handle_name/  s    '3|!!# #006)yk *( + + 	%%b$5&&r41AB4& !" % 	%r<   c                 0   |r|j                         j                         nd}| j                  |      rd|j                   dS d}t	        j
                  ||      sy| j                  j                  |||       | j                  j                  ||d       y)z0Collecte de l'email avec validation intelligenter@      👋 Bonjour zR !

J'ai besoin de votre *email professionnel*.

_Exemple: nom.prenom@exemple.com_r   uk   ⚠️ Email invalide.

*Format attendu:* nom.prenom@exemple.com

Veuillez entrer une adresse email valide.r   u   ✅ Email enregistré !

📋 Que souhaitez-vous partager ?

*1️⃣* - CV uniquement
*2️⃣* - LinkedIn uniquement  
*3️⃣* - CV + LinkedIn

Répondez avec le *numéro* de votre choix (1, 2 ou 3).)	rH   rG   rP   r   rI   r   r7   r   r   )r9   rh   r   rj   r   r   s         r:   r   z ConversationHandler.handle_emailF  s    0<""$**," &&u-$T^^$4 5" % % Lxxu-- 	&&r47&&r41BC;r<   c                     | j                  |      }|dk(  r| j                  j                  ||d       y|dk(  r| j                  j                  ||d       y|dk(  r| j                  j                  ||d       yy	)
z9Gestion du choix utilisateur avec extraction intelligenter^   r   u   📄 Parfait ! Envoyez votre *CV au format PDF*.

⚠️ Format: PDF uniquement
⚠️ Taille max: 10 MB

_Cliquez sur le bouton 📎 pour joindre votre fichier_r_   r   u   🔗 Parfait ! Envoyez l'URL de votre profil *LinkedIn*.

💡 *En fournissant votre lien, vous nous autorisez à récupérer automatiquement vos informations professionnelles publiques.*

_Exemple: https://linkedin.com/in/votre-profil_r`   u   📄 Parfait ! Commençons par votre *CV au format PDF*.

⚠️ Format: PDF uniquement
⚠️ Taille max: 10 MB

_Ensuite, je vous demanderai votre profil LinkedIn._

_Cliquez sur le bouton 📎 pour joindre votre fichier_u   ⚠️ Choix invalide.

Veuillez répondre avec *1*, *2* ou *3* :

*1️⃣* - CV uniquement
*2️⃣* - LinkedIn uniquement
*3️⃣* - CV + LinkedIn

_Entrez simplement le numéro de votre choix._)rg   r7   r   )r9   rh   r   rj   rf   s        r:   r   z!ConversationHandler.handle_choiceh  s     $$\2S=**2t]C; s]**2t5HI3 s]**2t]C;2r<   c                 ,   	 |dk(  r|r| j                  |      ryy|dk(  s|syt        j                  |      \  }}t        j                  |t        |            \  }	}
|	sd|
 dS t        j                  |      }d|t        j                         j                         |d}| j                  j                  |||       |j                  d	d
      j                         }|r)|j                  s| j                  j                  |||       t        |j                  dg             }t        |j                  dg             }| j                  j!                  ||d       d| d| dS # t"        $ r$}t$        j'                  d| d       Y d}~yd}~ww xY w)z0Traitement du CV avec gestion des messages texter   u   ⚠️ J'attends votre CV en PDF.

Cliquez sur le bouton *📎* (trombone) pour joindre votre fichier.

_Le fichier doit être au format PDF._u   ⚠️ Veuillez envoyer votre CV en *fichier PDF*.

Cliquez sur le bouton *📎* (trombone) en bas de l'écran pour joindre votre CV.

_Format: PDF uniquement_
_Taille max: 10 MB_uC   ⚠️ Aucun fichier reçu.

Envoyez votre CV en PDF (bouton 📎).r   uV   

Envoyez un fichier *PDF valide*.

_Cliquez sur le bouton 📎 pour joindre votre CV_r   r   r   r   r   r   r@   r   r   r   u5   ✅ *CV analysé avec succès !*

📊 *Résumé:*
- r   u%   expériences professionnelles

━━━━━━━━━━━━━━━━

🔗 Souhaitez-vous ajouter votre profil *LinkedIn* ?

💡 *Cela permettra d'enrichir votre profil automatiquement.*

Répondez :
- *Oui* - Envoyez votre URL LinkedIn
- *Non* - Tapez *"terminer"* pour finaliser   ❌ Erreur CV: Tr   Nu   ❌ Erreur lors de l'analyse du CV.

Vérifiez que:
- Le fichier est un PDF valide
- Le PDF contient du texte
- Taille < 10 MB

Réessayez en joignant un nouveau fichier.)rP   r   r   r	   r   rL   r   r   r   r   r7   r   r   rH   r   r   r   r   r   r   )r9   rh   r   rk   rl   rm   rj   r   r   r   r   r   r   r   r   r   r   s                    r:   r   zConversationHandler.handle_cv  s   N	.A~,..|<* A~Y* +9*G*G	*R'M<->>|SQ^M_`MHcu %3 6 6 ,55mDK &%'0::<"-	G ,,Rw? &//*b9??AK4==!!11"dKH{x<=LKOOL"=>I**2t5IJ . + 
,	/ /   		.LL?1#.L>.		.s)   E& E& AE& &C?E& &	F/FFc                 B   |r|j                         nd}| j                  |      ry|j                         dv r-| j                  j	                  ||       | j                  |      S t        j                  d|        t        j                  |      \  }}}|sd| dS | j                  j                  |||       |j                  di       j                  dd      j                         }|r| j                  j                  |||       | j                  j                  ||d	       t        |j                  di       j                  d
            }	|j                  xr |j                  i k7  }
|
r/| j                  j	                  ||       | j                  ||	      S y)z8Collecte du profil LinkedIn avec validation intelligenter@   u   🔗 J'attends l'URL de votre profil LinkedIn.

*Format attendu:* https://linkedin.com/in/votre-nom

Ou tapez *"terminer"* si vous n'avez pas de profil LinkedIn.)r/   r-   skipterminerpasseru   🔍 Début scraping LinkedIn: r   zj

*Format attendu:* https://linkedin.com/in/votre-nom

Ou tapez *"terminer"* pour finaliser sans LinkedIn.r   r   r   r   scrapedu   ✅ *Profil LinkedIn enregistré !*

📄 Souhaitez-vous ajouter votre *CV* ?

Répondez :
- *Oui* - Envoyez votre CV en PDF
- *Non* - Tapez *"terminer"* pour finaliser)rH   rP   rG   r7   mark_completedget_completion_messager   r   r
   r   r   r   r   r   r   r   )r9   rh   r   rj   r   r   r   r   r   r   r   s              r:   r   z#ConversationHandler.handle_linkedin  s   -9\'')r
 &&z2@ !LL,,R6..t445j\BC&6&J&J:&V#mse $4 7 7 	))"dMB *--nbAEEjRTU[[]--b$8IJ&&r41EF 1 1." E I I* UV4$,,""4,,R6..t=M.NN/r<   c                    |r|j                         j                         nd}|dv r-| j                  j                  ||       | j	                  |      S |dkD  r| j                  |||||      S d|v r| j                  |||      S | j                  |      r@|j                  xr |j                  i k7  }|j                  xr |j                  i k7  }	|sy|	sy|j                  xr |j                  i k7  }|j                  xr |j                  i k7  }	|s|	sy|sy|	sy	| j                  j                  ||       | j	                  |      S )
u   Gère ce qui reste à collecterr@   )r  r/   r-   r  finistopr  r   zlinkedin.comu   📄 J'attends votre CV en PDF.

Cliquez sur le bouton *📎* pour joindre votre fichier.

Ou tapez *"terminer"* pour finaliser sans CV.u   🔗 J'attends votre URL LinkedIn.

*Format:* https://linkedin.com/in/votre-nom

Ou tapez *"terminer"* pour finaliser sans LinkedIn.u   ⚠️ Que souhaitez-vous faire ?

📄 Envoyez votre CV (PDF)
🔗 Envoyez votre URL LinkedIn
✅ Tapez *"terminer"* pour finaliseru1   📄 Envoyez votre CV (PDF) ou tapez *"terminer"*u5   🔗 Envoyez votre URL LinkedIn ou tapez *"terminer"*)
rH   rG   r7   r  r  handle_cv_remaininghandle_linkedin_remainingrP   r   r   )
r9   rh   r   rj   rk   rl   rm   r   r   r   s
             r:   r   z$ConversationHandler.handle_remaining  sR   5A\'')//1r
TT,,R6..t44q=++BiL^__Z'11"dJGG &&|4\\8dllb&8F00PT5J5Jb5PL1
 "7 4$,,""4,,L1F1F"1Ll)
 JN,,R6..t44r<   c                    	 t        j                  |      \  }}t        j                  |t	        |            \  }}	|sd|	 dS t        j
                  |      }
d|t        j                         j                         |
d}| j                  j                  |||       |
j                  dd      j                         }|r)|j                  s| j                  j                  |||       | j                  j                  ||       | j!                  |      S # t"        $ r"}t$        j'                  d|        Y d}~y	d}~ww xY w)
u,   Traite le CV dans l'état awaiting_remainingr   z.

Envoyez un PDF valide ou tapez *'terminer'*.r   r  r   r@   r  Nu?   ❌ Erreur lors de l'analyse. Réessayez ou tapez *'terminer'*.)r   r   r	   r   rL   r   r   r   r   r7   r   r   rH   r   r   r  r  r   r   r   )r9   rh   r   rk   rl   rm   r   r   r   r   r   r   r   r   s                 r:   r  z'ConversationHandler.handle_cv_remainingK  s&   	U*8*G*G	*R'M<->>|SQ^M_`MHccU"RSS+55mDK &%'0::<"-	G ,,Rw? &//*b9??AK4==!!11"dKH,,R6..t44 	ULL?1#./T	Us   AD CD 	E D;;E r   c                    t        j                  |      \  }}}|sd| dS | j                  j                  |||       |j	                  di       j	                  dd      j                         }|r| j                  j                  |||       | j                  j                  ||       t        |j	                  di       j	                  d            }| j                  ||      S )u/   Traite LinkedIn dans l'état awaiting_remainingr   u#   

Réessayez ou tapez *'terminer'*.r   r   r@   r   r  )
r
   r   r7   r   r   rH   r   r  r   r  )	r9   rh   r   r   r   r   r   r   r   s	            r:   r  z-ConversationHandler.handle_linkedin_remainingl  s    &6&J&J:&V#mSE!FGG))"dMB *--nbAEEjRTU[[]--b$8IJ((T2 1 1." E I I* UV**49I*JJr<   c           	         |r]|j                         j                  d      j                         j                  d      s!| j                  |      rd|j                   dS |j                  xr |j                  i k7  }|j
                  xr |j
                  i k7  }d|j                   d|j                   d|rdnd	 d
|rd d	S d d	S )u+   État complété avec réponse aux messagesrp   r   r	  u    !

Votre profil est déjà enregistré.

Tapez */status* pour voir vos informations ou */aide* pour les commandes disponibles.uM   ✅ *Votre profil est déjà enregistré !*

📊 *Vos informations:*
- Nom: 

- Email: 
- CV: u   ✓ Enregistréu   ✗ Manquant
- LinkedIn: u   ✗ Non renseignéut  

━━━━━━━━━━━━━━━━

💡 *Mises à jour disponibles:*
- */cv* - Pour ajouter/modifier votre CV
- */linkedin* - Pour ajouter/modifier votre LinkedIn
- */email* - Pour modifier votre email
- */nom* - Pour modifier votre nom

━━━━━━━━━━━━━━━━

Pour tout réinitialiser: */reset*
Pour voir les commandes: */aide*)rH   r   rP   r   r   r   r   )r9   r   rj   cv_oklinkedin_oks        r:   r   z$ConversationHandler.handle_completed  s      2 2 4 : :6 B H H J U UVY Z**<8((8 9V Y Y 3!3++K0E0E0K 	 

** !~6 7"-H I!$ 	$ 4HH I!$ 	$r<   r  c                    |j                   xr |j                   i k7  }|j                  xr |j                  i k7  }d|j                   d|j                   g}d}|r|j	                  d       |r|r|j                  j                  di       }|j                  dd      }t        |j                  dg             }	t        |j                  dg             }
|j	                  d	|j                  j                  d
d              d|xs d d|	 d|
 }n/|j	                  d	|j                  j                  d
d       d       dj                  |      }d|j                   d| | dS )u3   Message de fin avec informations LinkedIn scrapéesu	   ✓ Nom: u   ✓ Email: r@   u   ✓ CV: Analysé et enregistrér   r   r   r   u   ✓ LinkedIn: r   u3   

📊 *Données LinkedIn récupérées:*
- Poste: r   r   r   u    (enregistré)
u   🎉 *Félicitations uL    !*

Votre profil a été enregistré avec succès.

📋 *Récapitulatif:*
u<  

━━━━━━━━━━━━━━━━

Notre équipe examinera votre profil et vous contactera si votre profil correspond à nos besoins.

💡 Vous pouvez modifier vos informations:
- */cv* - CV
- */linkedin* - LinkedIn
- */email* - Email
- */nom* - Nom

Merci et à bientôt ! L'équipe Karaba AI 🚀)r   r   r   r   appendr   rL   join)r9   r   r  r   r   recap_lineslinkedin_detailsr   r   r   r   recaps               r:   r  z*ConversationHandler.get_completion_message  s    4$,,""4,,L1F1F"1L '($**&

 @A#4488L'++J; 0 0r BC	"<#3#3Hb#AB""^D4I4I4M4MeUW4X3Y#Z[(
 
&&	' ( $"  ""^D4I4I4M4MeUW4X3YYg#hi		+&((8 9
  03 	3r<   c                 <    | j                   j                  ||       y)u   Réinitialiserul   🔄 *Conversation réinitialisée*

Vos données ont été effacées.

Envoyez un message pour recommencer.)r7   
reset_userr   s      r:   r   z ConversationHandler.handle_reset  s    $$R.(r<   c                    ddddddddd	d
ddd}|j                   xr |j                   i k7  }|j                  xr |j                  i k7  }d|j                  |j                  d       d|j                  xs d d|j
                  xs d d|rdnd d|rdnd d|j                  rdnd d|j                  r|j                  j                  d      nd }|j                  dk(  r|dz  }|S )zAfficher le statutu   DébutzEn attente du nomzEn attente de l'emailzEn attente du choixzEn attente du CVzEn attente LinkedInzEn attente des infos restantesu   ✅ Complétéu   📝 Mise à jour CVu   📝 Mise à jour LinkedInu   📝 Mise à jour Emailu   📝 Mise à jour Nom)r   r   r   r   r   r   r   r   r   r   r   r   u-   📊 *Statut de votre inscription*

*État:* Inconnuz

*Informations:*
- Nom: u   ❌r  r  u   ✅r   u   
- Complété: uK   

━━━━━━━━━━━━━━━━

Dernière interaction: z%d/%m/%Y %H:%Mr   r   u   

━━━━━━━━━━━━━━━━

💡 *Mises à jour:*
- */cv* - CV
- */linkedin* - LinkedIn
- */email* - Email
- */nom* - Nom)	r   r   r   r   r   r   registration_completedlast_interactionstrftime)r9   r   statesr!  r"  
status_msgs         r:   r   z!ConversationHandler.handle_status  s8     054-!6"B)1!=74
 3!3++K0E0E0K

**T,,i
8	9 : 	%  !

**
	 u5! "!Uu- .33u? @ MQLaLa--667GHglmq
 ""k1  J r<   c                      y)Aideug  ℹ️ *Commandes disponibles:*

*Inscription:*
*/reset* - Pour recommencer l'inscription
*/status* - Pour voir votre statut
*/aide* - Pour afficher cette aide

*Mises à jour:*
*/cv* - Pour ajouter/modifier votre CV
*/linkedin* - Pour ajouter/modifier LinkedIn
*/email* - Pour modifier votre email
*/nom* - Pour modifier votre nom

━━━━━━━━━━━━━━━━

*Processus:*
1️⃣ Nom complet (prénom + nom)
2️⃣ Email professionnel
3️⃣ Choix: CV, LinkedIn ou les deux
4️⃣ Envoi des documents

*Offres d'emploi:*
/tag-de-l'offre - Voir les détails d'une offre
/submit-tag-de-l'offre - Postuler à une offre
/status-job-tag-de-l'offre - Suivre sa candidature

💡 _Une fois votre inscription terminée, vous pouvez mettre à jour chaque élément individuellement avec les commandes de mise à jour ou postuler à des offres d'emploi._ r8   s    r:   r   zConversationHandler.handle_help  s    tr<   r   c                 n    t        j                  |      \  }}}|sd| dS t        j                  |      S )u?   Récupère et affiche les détails d'une offre d'emploi par tagr   uL   

Vérifiez le tag de l'offre et réessayez.

_Exemple: /dev-backend-senior_)r   get_offer_by_tagformat_offer_message)r9   r   r   offerr  s        r:   r   z%ConversationHandler.handle_view_offer3  sE    $5$F$Fs$K!	yk * " " !55e<<r<   c                    |j                   syt        j                  |      \  }}}|sd| dS |j                  dd      }|j                  dd      }t        j                  ||j
                        \  }}	}|s;|dk(  r1|	rt        j                  |	|      nd}
|
r	d	|
 d
| dS d| d| d
| dS d| S d| d| d| dS )u9   Permet à l'utilisateur de postuler à une offre d'emploiu   ⚠️ Vous devez d'abord compléter votre inscription avant de postuler.

Terminez votre inscription, puis réessayez.

_Tapez /aide pour voir les commandes._r   u,   

Vérifiez le tag de l'offre et réessayez.titlezl'offrecompany_namer@   already_appliedu5   ⚠️ *Vous avez déjà postulé à cette offre !*

z

Tapez */status-job-z * pour suivre votre candidature.uC   ⚠️ *Vous avez déjà postulé à cette offre !*

📋 *Offre:* u   
🏢 *Entreprise:* r   u:   🎉 *Candidature envoyée avec succès !*

📋 *Offre:* ur   
📊 *Statut:* En attente de traitement

Vous serez contacté(e) si votre profil correspond.

Tapez */status-job-)r.  r   r7  r   apply_to_offeridformat_application_status)r9   rh   r   r   r   r9  r  offer_titlecompanyresultr2  s              r:   r   z)ConversationHandler.handle_apply_to_offer@  s5    *** %6$F$Fs$K!	yk *+ . . ii3))NB/ &7%E%Ec477%S"--ag.HHQ\]mo
  58	< < m 9 58< < I;))m 9 
 58< 	<r<   c                    |j                   syd}t        j                  |      \  }}}|r|j                  dd      }t        j                  ||j
                        \  }}	}
|s	d|
 d| dS t        j                  |	|      S )z#Affiche le statut d'une candidatureu_   ⚠️ Vous devez d'abord compléter votre inscription.

_Tapez /aide pour voir les commandes._r@   r;  r   u5   

Vérifiez le tag ou postulez d'abord avec */submit-z*.)r.  r   r7  r   get_application_statusr?  r@  )r9   rh   r   r   rA  offer_successr9  _r   applicationr  s              r:   r   z-ConversationHandler.handle_application_statust  s    ***
 "3"D"DS"Iua))GR0K +<*R*RSVX\X_X_*`'iyk *4475> > !::;TTr<   )r   NNr6   )F)+__name__
__module____qualname____doc__rC   NEGATIVE_WORDSr;   strr   rP   tuplerY   r\   r   rg   r   intr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r  r   r   r   r   r   r   r5  r<   r:   r   r      s   2N*3 4 2 #  %c	*:  D# $ "3 8C= > "&l@l@ l@ 	l@
 l@ l@  l@ 
l@`!7 !S !8!! !!3 !!F!g ! !,!W !s !08#' 8#C 8#TW 8#mp 8#ux 8#t7+w 7+C 7+TW 7+r+G + +QT +>+7 + +PS +>8 8c 8S 8&%g %3 %3 %. ;w  ;C  ;C  ;D+2 +2S +2S +2ZP.G P.c P.c P._b P.ru P.  BE P.d1/' 1/s 1/s 1/f/57 /5 /5PS /5`c /5y| /5  BE /5bUg U UPS Uil Uqt UBKG Ks Ks K&"$3 "$# "$H43D 43S 43l(w ( (.S .`tS tB=S =S =2< 2<C 2<C 2<hUG U U Ur<   r   )rL  loggingrI   r   typingr   r   r   sqlalchemy.ormr   app.services.user_servicer   app.services.cv_parserr	   app.services.linkedin_servicer
   app.services.twilio_servicer   app.services.job_offer_servicer   app.schemasr   	getLoggerrI  r   r   conversation_handlerr5  r<   r:   <module>r\     s\     	  ' ' " 1 4 : 6 < "			8	$tU tUp# +, r<   