
    {ip                   R   d dl m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
Z
d dlZd dlZd dlm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mZ d dlmZ d dlm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*m+Z+ d dl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7m8Z8 d dl9m:Z:  ed      Z;dZ<dZ=dZ>dZ?dZ@ddhZAddhZBd d!heAeBZCd"ZDdd#ZEd$ZFd%ZGd&ZHd'ZId(ZJd)ZKh d*ZL ej                  d+ej                         ej                  d,ej                         ej                  d-ej                         ej                  d.ej                         ej                  d/ej                         ej                  d0ej                         ej                  d1ej                         ej                  d2ej                        fZO ej                  d3ej                         ej                  d4ej                         ej                  d5ej                         ej                  d6ej                         ej                  d7ej                         ej                  d8ej                        fZPe$j                  e$j                  e$j                  fZTd9ZUd:ZVd;ZWd<ZX ej                  d=ej                        ZYd d>d>d>d?dd@dAdBdCdDdEdFdGZZg dHZ[g dIZ\g eXe[ZX G dJ dKe      Z]e G dL dM             Z^e G dN dO             Z_ G dP dQe`      ZaddRZbddSZcddTZdddUZeddVZfdWdXddYZgdWdXddZZhdWdXdd[Zid\dXdd]Zjd\dXdd^Zkdd_Zl	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd`ZmddaZnddbZoddcZpdddZq	 	 	 	 	 	 	 	 ddeZr	 	 	 	 	 	 	 	 ddfZsddgZtddhZuddiZvddjZwddk	 	 	 	 	 	 	 	 	 ddlZxddmZyddnZzddoZ{ddpZ|ddqZ}	 	 	 	 	 	 	 	 	 	 ddrZ~	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddsZddtZ	 	 	 	 	 	 	 	 	 	 dduZddvZddwZddxZddyZddzZdd{Zdd|Zdd}Zdd~ZddZddZddZddZddZddZddZddZddZddZddZddZddZddZddZddZddZ	 	 	 	 	 	 	 	 	 	 ddZddZddZddZddZddZddZdd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 ddZddZddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZddZddZ	 	 	 	 	 	 	 	 ddZdddZ	 ddd	 	 	 	 	 	 	 	 	 ddZddZdddZddZddZddZddZddZd dZd dZddZddZ	 	 	 	 	 	 	 	 ddZdjw                         ZddZddZddZ	 	 	 	 	 	 	 	 ddZddZddZd	dZÐd
dZĐd
dZŐddZƐddZǐddZȐd
dZɐd
dZy(      )annotations)	dataclass)datedatetimetime	timedelta)SequenceMatcherN)ZoneInfo)HTTPException)	BaseModelFieldValidationError)select)Session
joinedload)get_settings)WhatsAppBookingSession)Customer)ReservationReservationSourceReservationStatus)Room)Table)ReservationCreateReservationUpdate)RoomAssignmentCandidatecombine_date_timelist_available_room_candidatesreservations_for_assignmentresolve_preferred_room_ids"select_best_candidate_across_rooms)normalize_customer_phone)delete_reservationget_reservation_or_404update_reservation)current_time_contextzEurope/Rome            booking-automationcancellation_collectingcancellation_disambiguationmodification_lookupmodification_update
collectingawaiting_confirmation)lascia stareznon importastopzferma tuttozannulla richiestac                 l    t               } ddi}| j                  xs dj                         }|r||d<   |S )NzContent-Typezapplication/json zX-Internal-API-Token)r   llm_proxy_internal_tokenstrip)settingsheaderstokens      APRENOTAZIONI_IA/backend/app/services/booking_assistant_service.pybuild_internal_llm_headersr<   6   s@    ~H12G..4";;=E*/&'N    )cancellannullelimindisdicrimuov)
modificcambiaspostaaggiungtogliriducaumentposticipanticipaggiorn)znuova prenotazionezprenotazione nuovazvoglio prenotarezvorrei prenotarezdevo fare una prenotazionezvoglio fare una prenotazionezfare una prenotazionezne voglio fare una nuovazvoglio farne una nuovazprenotare un tavolozvoglio un tavolo)zva bene il mio numerozil mio numero va benezusa il mio numerozlascia il mio numerozresta il mio numerozresta questo numerozva bene questo numerozcontattate mezcontatta mezscrivete a mezchiamate me)
znumero di paoloznumero di luiznumero di leizcontattate luizcontattate leizcontattate paolozchiamate luizchiamate leizscrivete a luizscrivete a lei)numerotelefonocell	cellularecontattowhatsapp>   	ciao ciaobuon pomeriggioehiheyciaosalve	buonasera
buongiornoz^\bci\s+sono\s+prenotazion(?:i)?\s+per\s+(?:oggi|domani|dopodomani|stasera|staser[a]?|pranzo)\bzf\bci\s+sono\s+prenotazion(?:i)?\s+per\s+(?:lunedi|martedi|mercoledi|giovedi|venerdi|sabato|domenica)\bz"\bci\s+sono\s+altre?\s+prenotazionz@\bquante?\s+prenotazion(?:i)?\s+(?:ci\s+sono|avete|ci\s+avete)\bz"\bchi(?:\s+altro)?\s+ha\s+prenotatz\ba\s+nome\s+di\s+chi\bz\baltri?\s+clientz(\baltre?\s+persone\b.*\bhanno\s+prenotatz \bho\s+gia\s+prenotazion(?:i)?\bz$\bho\s+prenotazion(?:i)?\s+attive?\bz\bho\s+prenotatz\brisulta\b.*\bprenotazionz(\bquali\b.*\bprenotazion(?:i)?\b.*\bho\bz2\bci\s+sono\s+prenotazion(?:i)?\s+a\s+mio\s+nome\b)confermozok confermozva beneperfettoprocediprenotafissa)annullacancellar2   znon confermoznon va bene)prenottavolpostocopertpersonr>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   )domani
dopodomanioggistaseraquesta seraz\b(prenot|tavol|posto|copert|persona|persone|domani|oggi|stasera|staser|sabato|domenica|lunedi|martedi|mercoledi|giovedi|venerdi|cancell|annull|elimin|disdic|rimuov|modific|cambia|sposta|aggiung|togli|riduc|aument|posticip|anticip|aggiorn|\d{1,2}:\d{2})                     	   
   )zeroununounaduetrequattrocinqueseisetteottonovediecilunedimartedi	mercoledigiovedivenerdisabatodomenica)gennaiofebbraiomarzoaprilemaggiogiugnoluglioagosto	settembreottobrenovembredicembrec                      e Zd ZU dZded<   dZded<   dZded	<   dZded
<    eddd      Z	ded<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   y)BookingExtractionFboolbooking_relatedotherstrintentN
str | Nonereservation_date
start_timerl   x   )defaultgele
int | Noneguestscustomer_namecustomer_phonearea_preferencenoteslow
confidence)__name__
__module____qualname__r   __annotations__r   r   r   r   r   r   r   r   r   r    r=   r;   r   r      sp    !OT!FC#'j'!J
!tc:FJ: $M:$!%NJ%"&OZ&E:Jr=   r   c                  >    e Zd ZU ded<   ded<   dZded<   dZded<   y)	BookingAutomationResultr   replyassistant_modelr+   routeNzdict[str, object] | Nonetrace)r   r   r   r   r   r   r   r=   r;   r   r      s"    J%E3%&*E#*r=   r   c                  b    e Zd ZU ded<   ded<   ded<   ed
d       Zedd       Zedd       Zy	)AvailabilitySnapshotzlist[RoomAssignmentCandidate]requested_optionsfallback_optionszset[int] | Nonepreferred_room_idsc                ,    t        | j                        S N)r   r   )selfs    r;   has_requested_availabilityz/AvailabilitySnapshot.has_requested_availability  s    D**++r=   c                T    | j                   D cg c]  }|j                   c}S c c}w r   )r   	room_namer   options     r;   requested_room_namesz)AvailabilitySnapshot.requested_room_names  s"    /3/E/EFV  FFF   %c                T    | j                   D cg c]  }|j                   c}S c c}w r   )r   r   r   s     r;   fallback_room_namesz(AvailabilitySnapshot.fallback_room_names  s"    /3/D/DEV  EEEr   N)returnr   )r   	list[str])r   r   r   r   propertyr   r   r   r   r=   r;   r   r      sR    4433'', , G G F Fr=   r   c                      e Zd Zy)ReservationNoLongerAvailableN)r   r   r   r   r=   r;   r   r     s    r=   r   c                v   t        t        j                        j                  t        t        j                  t        j
                  k(        j                  t        j                  | k(  t        j                  j                  d            j                  d      }|j                  |      j                         d uS )NTrl   )r   r   idjoinr   room_idwherevenue_id	is_activeis_limitexecutefirst)r   dbstmts      r;   venue_has_active_tablesr     sx    uxx	dDGGu}},	-	t}}(%//*=*=d*C	D	q	 	 ::d!!#4//r=   c                    t        |       }t        j                  dd|      }t        j                  dd|      j                         S )Nz
[^a-z0-9]+ \s+)normalize_temporal_textresubr7   value
normalizeds     r;   normalize_match_textr     s:    (/JsJ7J66&#z*0022r=   c                @    t        |       }|sg S |j                         S r   )r   splitr   s     r;   tokenize_for_matchingr   $  s#    %e,J	r=   c                "   t        |       t        |      k7  ryt        t        | |            D cg c]  \  }\  }}||k7  s| }}}}t        |      dk7  s|d   |d   dz   k7  ry|d   }|d   }| |   ||   k(  xr | |   ||   k(  S c c}}}w )NFrm   rl   r   )len	enumeratezip)leftrightindexlvalrval
mismatchesr   seconds           r;   !is_adjacent_transposition_variantr   +  s    
4yCJ3<Su=M3N__/E<D$RVZ^R^%_J_
:!z!}
10AAqME]F;%-'HDLE%L,HH `s   B
B
c                z    t        t        |       t        |            }|dk  r| |k(  S |dk\  rdnd}| d | |d | k(  S )Nrl   rn   rm   )minr   )r   r   shortestprefix_lengths       r;   has_shared_prefixr   6  sM    3t9c%j)H1}u}!QAAM5-#888r=   gQ?	min_ratioc                  | |k(  ry| r|syt        |      dk\  r,| j                  |      rt        |       t        |      z
  dk  ryt        |       t        dt        |      dz
        k\  r)t        |      t        |       k\  r|j                  |       ryt        t        |       t        |      z
        dkD  ryt	        | |      syt        | |      ryt        d | |      j                         |k\  S )NTFrn   rl   r)   rm   )r   
startswithmaxabsr   r   r	   ratio)r:   expectedr   s      r;   fuzzy_token_matchr  >  s    
8}e..x8SZ#h-=W[\=\
5zSCMA-..3x=CJ3NS[SfSfglSm
3u:H%&*UH-(941779YFFr=   c               ,   t        |       }t        |      |rsyt              dk(  rt        fd|D              S t              }t        t        |      |z
  dz         D ]+  }||||z    t	        fdt        |      D              s+ y y)NFrl   c              3  @   K   | ]  }t        |d            yw)r   r   Nr  ).0r:   r   phrase_tokenss     r;   	<genexpr>z/text_contains_phrase_variant.<locals>.<genexpr>V  s$     oW\$UM!,<	RRo   c              3  F   K   | ]  }t        |   |            ywr   Nr  )r  r   r   r  windows     r;   r  z/text_contains_phrase_variant.<locals>.<genexpr>Z  s.      
 fUm]5-AYWW
s   !T)r   r   anyrangeall)textphraser   message_tokenswindow_sizestartr  r  s     `   @@r;   text_contains_phrase_variantr  P  s    *40N)&1M
=Qo`nooom$Ks>*[81<= (;< 
{+
 
  r=   c               0     t         fd|D              S )Nc              3  :   K   | ]  }t        |         ywr
  )r  )r  r  r   r  s     r;   r  z3text_contains_any_phrase_variant.<locals>.<genexpr>c  s     eSY+D&INNe   r  )r  phrasesr   s   ` `r;    text_contains_any_phrase_variantr  b  s    e]deeer=   zG?c          	         t        |       D ]I  }|j                  |      r y|d t        t        |      t        |      dz          }t	        |||      sI y y)NTrm   r   F)r   r   r   r   r  )r  stemr   r:   	candidates        r;   text_contains_stem_variantr  f  s[    &t, D!:CE
CIM:;	Y	B r=   c               0     t         fd|D              S )Nc              3  :   K   | ]  }t        |         ywr
  )r  )r  r  r   r  s     r;   r  z1text_contains_any_stem_variant.<locals>.<genexpr>q  s     ]t)$	JJ]r  r  )r  stemsr   s   ` `r;   text_contains_any_stem_variantr#  p  s    ]W\]]]r=   c                    t         j                  |       ryt        |       }t        j                  d|      ryt	        |t
              ryt        |t              S )NTz\b\d{1,2}:\d{2}\b)BOOKING_KEYWORDSsearchr   r   r#  BOOKING_KEYWORD_STEMSr  BOOKING_TEMPORAL_KEYWORDSincoming_textr   s     r;   message_has_booking_keywordsr+  t  sK    }-%m4J	yy%z2%j2GH+J8QRRr=   c                   t        |||       }|)|j                  dv rt        |       | j                          |'t	        ||      rt        |       | j                          t        |      r|nd }|d u}t        |||      \  }	}
|xs |	j                  xs t        |      }|sy t        |      r-t        |||       }t        t        |      t        |
            S t        ||| |      }t	        ||      rt        |       t        ||	|      r|j                  t         vrd|_        i |_        t%        |j"                        }|j&                   |j)                  d      s|j&                  |d<   t+        |      r$|j)                  d	      s|j-                         |d	<   t/        ||	||j                         t1        |      rGt3        |	|      s;d
|_        i |_        d |_        | j                          t        dt        |
            S t5        ||||||       }t7        |t8              r4d|_        ||_        | j                          t        |t        |
            S |j:                  |d<   d|_        |j:                  |_        t=        |||       }|[|\  }}|r d|_        i |_        |j:                  |_        nd|_        ||_        | j                          t        |t        |
            S ||_        | j                          t        t?        |      t        |
            S tA        ||	|      r|j                  tB        vrt        |       d|_        i |_        t%        |j"                        }t+        |      r$|j)                  d	      s|j-                         |d	<   tE        ||	       t1        |      rFtG        |	      s;d
|_        i |_        d |_        | j                          t        dt        |
            S tI        |      }|r=d|_        ||_        | j                          t        tK        |      t        |
            S tM        |||       }|s=d|_        ||_        | j                          t        tO        |      t        |
            S tQ        |      dkD  r>d|_        ||_        | j                          t        tS        ||      t        |
            S tU        |d   j:                  |       }d
|_        i |_        d |_        | j                          t        tW        |      t        |
            S t%        |j"                        }||d<   ||d<   t+        |      r$|j)                  d	      s|j-                         |d	<   t+        |      r|j-                         |d<   tY        ||	       ||d<   t[        ||||        t]        |      rRt_        |      rFd|_        ||_        | j                          t        ta        tc        |            t        |
            S y te        |      r6||_        | j                          t        tg        |      t        |
            S ti        |	|      rFtk        |      s;d
|_        i |_        d |_        | j                          t        dt        |
            S |j                  dk(  rItm        |	|      r<tc        |      }|r=d|_        ||_        | j                          t        to        |      t        |
            S tq        ||       s=d|_        ||_        | j                          t        ts        |      t        |
            S tu        |tw        |d         ty        |d         t{        |d          t{        |d         |j)                  d!      d | "      }|j|                  rht        ||| #      }|Xd|_        |j:                  |_        i |_        | j                          t        t        |t        |            t        |
            S t        |tw        |d         ty        |d         t{        |d          t{        |d         |j)                  d!      | $      }|D cg c]  }|j                  d%       c}|d&<   d|_        ||_        | j                          t        t        ||d't9        |j)                  d!      xs d(      j-                         xs d )      t        |
            S tc        |      }|r=d|_        ||_        | j                          t        to        |      t        |
            S t        ||*      }|4d|_        ||_        | j                          t        |t        |
            S tw        |d         }ty        |d         }tq        ||       sBg |d&<   d|_        ||_        | j                          t        ts        |      t        |
            S tu        |||t{        |d          t{        |d         |j)                  d!      d | "      }|j                  r|j                  s|j                  rtQ        |j                        dk(  r|j                  d   |d!<   g |d&<   tQ        |j                        dk(  rdnd|_        ||_        | j                          t        t        |t9        |j)                  d!      xs d(      j-                         |j                  +      t        |
            S tQ        |j                        dkD  rY|j                  sMg |d&<   d|_        ||_        | j                          t        t        ||j                        t        |
            S |j|                  r`g |d&<   d|_        ||_        | j                          |j                  r|j                  d   nd }t        t        ||      t        |
            S t        |||t{        |d          t{        |d         |j)                  d!      | $      }|D cg c]  }|j                  d%       c}|d&<   d|_        ||_        | j                          t        t        ||t9        |j)                  d!      xs d(      j-                         xs d ,      t        |
            S c c}w c c}w )-N)r   r   >   	cancelled	confirmed)r*  sessionsender_name)r   sender_phoner   )r   r   )r1  r   r   r/  r.   target_reservation_idr   r-  zLVa bene, interrompo la modifica. Se vuoi, scrivimi pure come posso aiutarti.)r   r1  r0  r/  draftr   r/   )r3  reservationr   r.  r,   zTVa bene, interrompo la richiesta di cancellazione. Se ti serve altro, scrivimi pure.)r   r3  r   rl   r-   r   r   r1  r0  duration_minutes)r3  r*  r   r   r0   zuVa bene, nessun problema: non blocco nulla. Se vuoi, posso aiutarti con un altro orario o con una nuova prenotazione.r1   r   r   r   r   r   r   r   r   r5  r   exclude_reservation_idr   )r3  r   r   )r   r   requested_timer   r5  r   r   %H:%Malternative_timesTr5   )
is_recheckrequested_area)r3  r*  )r<  available_room_namesr<  )Nload_active_sessionstatusreset_sessionflushshould_restart_as_new_booking!should_use_session_for_extractionextract_booking_messager   r+  "is_self_reservation_lookup_request!find_reservations_for_self_lookupr   #build_self_reservation_lookup_replybuild_booking_model_labelget_or_create_sessionshould_handle_modification_flowMODIFICATION_SESSION_STATUSESr3  normalize_draftreservation_idgetis_meaningful_namer7   &apply_modification_extraction_to_draftis_abort_flow_intent#extraction_has_modification_updatesresolve_modification_target
isinstancer   r   maybe_apply_modificationbuild_modification_prompt_replyshould_handle_cancellation_flowCANCELLATION_SESSION_STATUSES&apply_cancellation_extraction_to_draft#extraction_has_cancellation_updates#compute_cancellation_missing_fields'build_cancellation_missing_fields_reply"find_reservations_for_cancellation"build_cancellation_not_found_replyr   'build_cancellation_disambiguation_replyr#    build_cancellation_success_replyapply_extraction_to_draft(maybe_apply_area_preference_from_messageis_greeting_only_message$draft_has_meaningful_booking_context$build_greeting_booking_context_replycompute_missing_fields&is_other_customer_booking_info_request'build_other_customer_booking_info_replyis_decline_intent$message_has_explicit_booking_updatesis_confirmation_intentbuild_missing_fields_replyr   *build_capacity_configuration_missing_replybuild_availability_snapshotparse_iso_dateparse_hhmm_timeintr   %create_confirmed_whatsapp_reservationbuild_confirmed_replyget_assigned_room_namesuggest_alternative_slotsstrftimebuild_unavailable_reply.maybe_resolve_reference_phone_for_other_personr   r   r   r   &build_preferred_area_unavailable_replyr   build_area_preference_promptbuild_confirmation_reply) r   r1  r0  r*  r   turn_duration_minutesr/  active_sessionhas_open_session
extractionextraction_modelis_booking_flowreservationsmodification_drafttarget_reservationmodification_result
reply_textis_completedcancellation_draftmissing_cancellation_fields
candidatesdeleted_snapshotr3  missing_fieldsavailabilityr4  alternativesr   reference_phone_replyrequested_dater8  assigned_room_names                                    r;   maybe_handle_booking_messager    sk    ",bIGw~~1KKg

<WmTg

 A' JWPTN%T1#:#$ J  's**D*DsHderHsO)-88(Yejlm&5lC56FG
 	

 $UWahiG$Wm<g&w
MJ>>!>>2GNGM,W]];!!-6H6L6LMd6e:A:P:P67k*3E3I3I/3Z2=2C2C2E/.NN		
  .7Z[egt7u(GNGM%)G"HHJ*d 9:J K 
 9%#$
 (#.2GN.GMHHJ*( 9:J K 
 7I6K6K23.!3!6!66$*

 *':$J!, ");)>)>&!6 2HHJ*  9:J K 
 +

&12DE56FG
 	

 'w
MJ>>!>>'"6GNGM,W]];k*3E3I3I/3Z2=2C2C2E/./A:N.7Z[e7f(GNGM%)G"HHJ*l 9:J K 
 'JJ\&]#&6GN.GMHHJ*=>YZ 9:J K 
 8$


 6GN.GMHHJ*89KL 9:J K 
 z?Q:GN.GMHHJ*=jJ\] 9:J K 
 .jm.>.>C$!%

&23CD56FG
 	

 GMM*E*E
(E.+&uyy/I!,!2!2!4o+&*002meZ0 5E
,#	  ./6)GN!GMHHJ*:;QRW;XY 9:J K  -m<

&9%@56FG
 	

 ]3<`an<o$!%

& J56FG
 	

 ~~005KJXe5f/6)GN!GMHHJ*0@ 9:J K 
 'R@)GN!GMHHJ*@G 9:J K 
 3+E2D,EF&u\':;uX' '9!:;!II&78#'	
 22?!K
 &!,)4& "
./7Mk7Z[$=>N$O 
 1+E2D,EF*5+>?uX' '9!:;!II&78
 LX%X%ennW&=%X!"%

&)"599->#?#E2FLLNVRV	 66FG
 	
 ,E2N%

&,^<56FG
 	

 K# (%

&'56FG
 	

 $E*<$=>N$U<%89N"H<%'!"%

&<UC56FG
 	

 /'!5?#U#567		"34#	L &&|/M/MR^RoRo|//0A5'3'G'G'JE#$%'!"478X8X4Y]^4^0dp

&8"599->#?#E2FLLN%1%E%E
 66FG
 	
 <,,-1,:Y:Y%'!"%

&.ul6W6WX56FG
 	

 ..%'!"0

EQEfEf\>>qAlp&*52DE56FG
 	

 -'%5?#U#567		"34L HT!Te%.."9!TE
!GNGMHHJ"%uyy):;ArBHHJRd

 22BC ] &YT "Us   ssc                (    | rt          d|  S t         S )N:)BOOKING_MODEL_LABEL)r  s    r;   rI  rI    s    %&a(8'9::r=   c                    | j                   g t        t        ddvryt        |t              ryt        |t
              ryt        |t              S )Nr0   r1   F)r@  rY  rL  r#  CANCELLATION_PATTERNSMODIFICATION_PATTERNSr  NEW_BOOKING_PATTERNS)r/  r*  s     r;   rC  rC    sj    ~~  E<  E?\  E^j  E  mD  E  E%m5JK%m5JK+M;OPPr=   c                R     t         t              syd}t         fd|D              S )NF)r   r   r   r:  lookup_reservation_datelookup_start_timenew_reservation_datenew_start_time
new_guestspending_new_guestsguest_deltar2  c              3  L   K   | ]  }j                  |      d dg dfv  y wNr5   r   rO  )r  keyr3  s     r;   r  z7draft_has_meaningful_booking_context.<locals>.<genexpr>3  s'     R3uyy~dBA%66Rs   !$)rU  dictr  )r3  meaningful_keyss   ` r;   re  re  "  s*    eT"O R/RRRr=   c                    | | j                   t        vry| j                   t        v s| j                   t        v ryt	        | j
                        S NFT)r@  ACTIVE_SESSION_STATUSESrY  rL  re  r3  r/  s    r;   rD  rD  6  sA    '..0GG~~66'..Li:i/>>r=   c                    | j                   t        v ryt        |t              }|s|j                  dk7  ryt        | j                        xs | j                   dk(  }|r| j                   dv r| j                  yy)NTmodifyFr1      r0   r1   )r@  rL  r#  r  r   r   r3  rN  )r/  r  r*  has_modify_keywordhas_open_booking_drafts        r;   rK  rK  >  st    
 ~~667G\]*"3"3x"?!'--0]GNNF]4]'..4["[`g`v`v`~r=   c                   | j                   t        v ryt        |t              }|s|j                  dk7  ryt        | j                        xs | j                  d uxs | j                   dk(  }|r| j                   dv rt        |      syy)NTcancelFr1   r  )	r@  rY  r#  r  r   r   r3  rN  )message_has_explicit_cancellation_updates)r/  r  r*  has_cancel_keywordr  s        r;   rX  rX  Q  s    
 ~~667G\]*"3"3x"?!'--0  DG4J4JRV4V  DZaZhZh  mD  [D'..4["[  eN  O\  e]r=   c                "    t        | t              S r   )r  FLOW_ABORT_PATTERNSr*  s    r;   rR  rR  d  s    +M;NOOr=   c                D    | sy dj                  d | D              }|xs d S )Nr5   c              3  B   K   | ]  }|j                         s|  y wr   isdigitr  	characters     r;   r  z)normalize_lookup_phone.<locals>.<genexpr>k  s     M99J9J9LYMs   )r   r   digitss     r;   normalize_lookup_phoner  h  s&    WWMMMF>Tr=   c                p    t        j                  dd| xs d      j                         j                         S )Nr   r   r5   )r   r   r7   casefoldr   s    r;   normalize_lookup_namer  o  s+    66&#-335>>@@r=   c                V    t        |       }t        |      }|sy||k(  xs
 ||v xs ||v S )NF)r  )reservation_namelookup_namenormalized_reservationnormalized_lookups       r;   reservation_name_matchesr  s  sI    23CD-k:"33 	7 66	7!%66r=   r  c                    ||S t        | |      }|3|j                  |k7  r||_        t        |       |j                          |S t	        | |di       }|j                  |       |j                          |S )N)r   r0   )contact_phoner   r@  r3  )load_latest_session_by_phoner   rA  rB  r   add)r1  r   r   r/  legacy_sessions        r;   rJ  rJ    s     1,2FN!""h.&.N#.)

$"	G FF7OHHJNr=   c                  |j                  t        t              j                  t        j                  | k(  t        j
                  |k(              }|y t        j                  t              t        t              z
  }|j                  }|"|j                  |j                  t              }|.||k  r)|j                  dvrt        |       |j!                          |S )Nhours)tzinfo>   r-  r.  )scalarr   r   r   r  r   r   nowROME_TZr   SESSION_TIMEOUT_HOURS
updated_atr  replacer@  rA  rB  )r1  r   r   r/  stale_beforer  s         r;   r?  r?    s    ii%&,,"00L@"++x7	
G <<(9;P+QQL##J*"3"3";''w'7
*|";Vp@pg

Nr=   c                  |j                  t        t              j                  t        j                  | k(        j                  t        j                  j                         t        j                  j                                     S r   )	r  r   r   r   r  order_byr  descr   )r1  r   s     r;   r  r    s^    99%&	%33|C	D	(3388:<R<U<U<Z<Z<\	] r=   c                .    d| _         i | _        d | _        y )Nr0   )r@  r3  rN  r  s    r;   rA  rA    s    !GNGM!Gr=   c                <    t        | t              si S t        |       S r   )rU  r  )	raw_drafts    r;   rM  rM    s    i&		?r=   c                `   |j                   r|j                   j                         | d<   |j                  r"|j                  j                         | d<   d| d<   |j                  r$t	        |j                        r|j                  | d<   |j
                  r$t        |j
                        r|j
                  | d<   |j                  t        |j                        | d<   |j                  r|j                  j                         | d<   |j                  r|j                  j                         | d	<   y y )
Nr   r   Treference_phone_confirmedr   r   r   r   r   )r   r7   r   r   is_valid_iso_dater   is_valid_hhmm_timer   rr  r   r   r3  r  s     r;   rb  rb    s
   !+!9!9!?!?!Ao  ",";";"A"A"C-1)*""'89T9T'U$.$?$? !!3J4I4I!J(33l$j//0h!!#-#=#=#C#C#E #))//1g r=   c           	        t        | j                  d      xs d      j                         }|rt        |||      }|rt	        |j                  t        t              j                  t        j                  j                  |            j                  t        j                                    }t        |      dk(  r|d   j                  | d<   y t        |||      }|sy t	        |j                  t        t              j                  t        j                  j                  |            j                  t        j                                    }t        |      dk(  r|d   j                  | d<   y y )Nr   r5   rl   r   )r   rO  r7   r    listscalarsr   r   r   r   in_r  namer   )r3  r*  r   r   existing_preferencematching_idsroom_optionsinferred_idss           r;   rc  rc    s    eii(9:@bAGGI1(<OQST

6$<+=+=dggkk,>W+X+a+abfbkbk+l mnL< A%+7?+?+?'(-hrJL

6$<#5#5dggkk,6O#P#Y#YZ^ZcZc#defL
<A#/?#7#7  r=   c                <   t        || |      }||D 	cg c]  }	|	j                  |k7  s|	 }}	t        | d||||t        j                  t
        j                  d |
      }
t        | ||      }t        |
| |||      }t        |
| ||      }t        |||      S c c}	w )Nr   
r   customer_idr   r   r5  r   r@  sourcer   r   r   )r   r   r   )
r   r   r   r   r.  r   rR   r    r   r   )r   r   r   r   r5  r   r7  r   	scheduledr4  prober   r   r   s                 r;   ro  ro    s     ,,<hKI)4=j[SiAi[j	j)) ** ))'E 4HorR6
- 6
	  +)- 9 ks
   BBc                l   |j                   r|j                   j                         | d<   |j                  r|j                  j                         | d<   |j                  r$t	        |j                        r|j                  | d<   |j
                  r&t        |j
                        r|j
                  | d<   y y y )Nr   r   r   r   )r   r7   r   r   r  r   r  r  s     r;   rZ  rZ     s    !+!9!9!?!?!Ao  ",";";"A"A"C""'89T9T'U$.$?$? !!3J4I4I!J(33l "Kr=   c                   t        |      }t        |      }t        |      }|j                  r|j                  j	                         | d<   |j
                  r|j
                  j	                         | d<   t        |      }|*|| d<   | j                  dd        | j                  dd        n|| j                  dd        |dk(  s| j                  d      r7|rt        |      r|| d<   |rt        |      r|| d	<   ||t        |      | d<   y |rt        |      r|| d
<   |rt        |      r|| d<   ||t        |      | d<   y y y )Nr   r   r  r  r  r/   r2  r  r  r  r  )extract_explicit_dateextract_explicit_timeextract_explicit_guest_countr   r7   r   extract_guest_deltapoprO  r  r  rr  )r3  r  r*  session_statusexplicit_dateexplicit_timeexplicit_guestsr  s           r;   rQ  rQ  +  s_    *-8M)-8M2=AO!+!9!9!?!?!Ao  ",";";"A"A"C%m4K*m		,%		&-		$		-&..%))<S2T.}=,9E()/>&3E"#&;+>"%o"6E,*=9+8'(+M:%2!""{':&)/&:"# (;"r=   c                ~    t        d | j                  | j                  | j                  | j                  fD              S )Nc              3  *   K   | ]  }|d dg fv  y wNr5   r   r  r   s     r;   r  z6extraction_has_cancellation_updates.<locals>.<genexpr>S  #       	dB^#   )r  r   r   r   r   r  s    r;   r[  r[  R  sD      ''!!$$%%	
  r=   c                    t        d t        |      t        |      t        |      | j                  | j
                  t        |      fD              S )Nc              3  *   K   | ]  }|d dg fv  y wr  r   r  s     r;   r  z6extraction_has_modification_updates.<locals>.<genexpr>_  s#      
 	dB^#
r  )r  r  r  r  r   r   r  r  r*  s     r;   rS  rS  ^  sR     
 "-0!-0(7$$%%.

 
 
r=   c           
         t        d | j                  | j                  | j                  | j                  | j
                  | j                  | j                  fD              S )Nc              3  *   K   | ]  }|d dg fv  y wr  r   r  s     r;   r  z1extraction_has_booking_updates.<locals>.<genexpr>m  s#       	dB^#r  )r  r   r   r   r   r   r   r   r  s    r;   extraction_has_booking_updatesr  l  s_      ''!!$$%%&&
  r=   c           	     v    t        d t        |       t        |       t        |       t	        |       fD              S )Nc              3  *   K   | ]  }|d dg fv  y wr  r   r  s     r;   r  z<message_has_explicit_cancellation_updates.<locals>.<genexpr>|  r  r  )r  r  r  extract_explicit_nameextract_explicit_phoner  s    r;   r  r  {  s@      "-0!-0!-0"=1	
  r=   c           
         t        d t        |       t        |       t        |       t	        |       t        |       fD              S )Nc              3  *   K   | ]  }|d dg fv  y wr  r   r  s     r;   r  z7message_has_explicit_booking_updates.<locals>.<genexpr>  s#      	 	dB^#	r  )r  r  r  r  r  r  r  s    r;   rk  rk    sH     	 "-0!-0(7!-0"=1
	 	 	r=   c                h    | j                   dk(  ryt        |t              xr t        |t               S )NconfirmT)r   r  CONFIRM_PATTERNSDECLINE_PATTERNSr  s     r;   rl  rl    s=    I%+M;KL UuV R r=   c                @    | j                   dv ryt        |t              S )N>   r  declineT)r   r  r  r  s     r;   rj  rj    s"    11+M;KLLr=   c                d   g }| j                  d      r#t        t        | j                  d                  s|j                  d       | j                  d      s|j                  d       | j                  d      s|j                  d       | j                  d      dv r|j                  d	       |S )
Nr   nomer   datar   orarior   r  numero di personerO  rP  r   appendr3  missings     r;   rg  rg    s    G99_%-?EIIoD^@_-`v99'(v99\"x yym+*+Nr=   c                    h dj                  t        |             r	 yt        |       dk(  r	d| d    dS dj                  | d d       d	| d    z   }d
| dS )N>   r  r  r  zjScusami, non ho capito bene la richiesta. Puoi riscrivermela indicando giorno, orario e numero di persone?rl   zCCerto, per completare la prenotazione mi serve ancora questo dato: r   .,  e zECerto, per completare la prenotazione mi servono ancora questi dati: )issubsetsetr   r   r  joineds     r;   rm  rm    s    .77N8KLO	
 >aTUcdeUfTgghiiYY~cr*+N24F3G.HHFRSYRZZ[\\r=   c                4     t         fdt        D              S )Nc              3  @   K   | ]  }|j                          y wr   r&  r  patternr*  s     r;   r  z9is_other_customer_booking_info_request.<locals>.<genexpr>  s     aw~~m,ar  )r  $OTHER_CUSTOMER_BOOKING_INFO_PATTERNSr  s   `r;   rh  rh    s    a<`aaar=   c                    t        |       }d}|s| dS t        |      dk(  r| d|d    dS dj                  |d d       d	|d    z   }| d
| dS )NzcMi dispiace, ma per privacy non posso condividere informazioni sulle prenotazioni di altri clienti.zR Se vuoi, posso comunque controllare subito la disponibilita per la tua richiesta.rl   z` Se vuoi, posso controllare la disponibilita per la tua richiesta: mi serve ancora questo dato: r   r%  r&  r'  r(  zb Se vuoi, posso controllare la disponibilita per la tua richiesta: mi servono ancora questi dati: )rg  r   r   )r3  r  
base_replyr,  s       r;   ri  ri    s    +E2Nm  opp
>al ,,:1,=+>aA	
 YY~cr*+N24F3G.HHF, **0	4r=   c                x    t        j                  dd| j                               j                         }|t        v S )Nu   [^\wÀ-ÿ]+r   )r   r   r  r7   GREETING_ONLY_PATTERNSr)  s     r;   rd  rd    s2    ]-C-C-EFLLNJ///r=   c                |    | syt        |       dk(  r	d| d    dS dj                  | d d       d| d    z   }d	| dS )
Nz_Ciao! Ti aiuto volentieri. Dimmi pure se vuoi confermare, modificare o cancellare la richiesta.rl   zWCiao! Ti aiuto volentieri. Per completare la prenotazione mi serve ancora questo dato: r   r%  r&  r'  r(  zYCiao! Ti aiuto volentieri. Per completare la prenotazione mi servono ancora questi dati: r   r   r+  s     r;   rf  rf    sf    p
>ahiwxyizh{{|}}YY~cr*+N24F3G.HHFfgmfnnoppr=   c                4     t         fdt        D              S )Nc              3  @   K   | ]  }|j                          y wr   r/  r0  s     r;   r  z5is_self_reservation_lookup_request.<locals>.<genexpr>  s     ]w~~m,]r  )r   SELF_RESERVATION_LOOKUP_PATTERNSr  s   `r;   rF  rF    s    ]<\]]]r=   c                    | j                  d      }| j                  d      }t        t        |xs d            rt        t        |xs d            syt        t        |      t        |             S )Nr0  r   r5   F)rO  rP  r   r  )r3  r0  r   s      r;   is_booking_for_other_personr=    sb    ))M*KIIo.Mc+"345=OPSTaTgegPh=i'K(8#m:LMMMr=   c                    t        | j                  d      xs d      j                         }t        | j                  d      xs | j                  d            }d| d| dS )Nr   zquesta personar1  r   z&Perfetto, la prenotazione sara a nome z?. Possiamo lasciare come numero di riferimento il tuo attuale (z), oppure se preferisci puoi inviarmi il numero della persona prenotata, cosi la contattiamo direttamente in caso di necessita.)r   rO  r7   mask_phone_for_reply)r3  r   r1  s      r;   (build_reference_phone_confirmation_replyr@    sg    		/2F6FGMMOM'		.(A(`UYYO_E`aL
0 @ > "9	9r=   c                      	 y)NzPer usarlo come numero di riferimento mi serve un recapito valido. Puoi inviarmelo in un formato corretto, per esempio +39 333 123 4567?r   r   r=   r;   #build_invalid_reference_phone_replyrB    s    	(r=   c                    | j                         t        fdt        D              ryt        d | D              dk\  S )Nc              3  &   K   | ]  }|v  
 y wr   r   )r  keywordlowereds     r;   r  z3message_looks_like_phone_attempt.<locals>.<genexpr>   s     
F'7g
F   Tc              3  <   K   | ]  }|j                           y wr   r  r  s     r;   r  z3message_looks_like_phone_attempt.<locals>.<genexpr>  s     Byy  "B   rn   )r  r  PHONE_REFERENCE_KEYWORDSsum)r*  rF  s    @r;    message_looks_like_phone_attemptrL    s9    $$&G

F-E
FFBMBBaGGr=   c                   t        |       s| j                  dd        y t        | j                  d            }t        | j                  d            }|r|r||k7  rd| d<   y | j                  d      ry t	        |      }|r|| d<   d| d<   y |j                         t        fdt        D              r-| j                  d      xs | j                  d      | d<   d| d<   y t        fdt        D              r2t        | j                  d      xs d      j                         }d	| d
S t        |      r
t               S t        |       S )Nr  r1  r   Tc              3  &   K   | ]  }|v  
 y wr   r   r  r1  rF  s     r;   r  zAmaybe_resolve_reference_phone_for_other_person.<locals>.<genexpr>  s     
L'7g
LrG  c              3  &   K   | ]  }|v  
 y wr   r   rO  s     r;   r  zAmaybe_resolve_reference_phone_for_other_person.<locals>.<genexpr>  s     
N'7g
NrG  r   zla persona prenotataz+Perfetto, allora inviami pure il numero di z' da usare come contatto di riferimento.)r=  r  r  rO  r  r  r  KEEP_SENDER_REFERENCE_PATTERNS OTHER_CONTACT_REFERENCE_PATTERNSr   r7   rL  rB  r@  )r3  r*  r1  current_customer_phoneexplicit_phoner   rF  s         @r;   ry  ry    sA   &u-		-t4)%))N*CDL3EII>N4OP,3I\3Y-1)*yy,-+M:N"0-1)*$$&G

L-K
LL"'))N";"ZuyyIY?Z-1)*

N-M
NNEIIo6P:PQWWY<]OKrss'62443E::r=   c                    g }| j                  d      r#t        t        | j                  d                  s|j                  d       | j                  d      s|j                  d       |S )Nr   znome della prenotazioner   zgiorno della prenotazioner   r"  s     r;   r\  r\  )  sU    G99_%-?EIIoD^@_-`0199'(23Nr=   c                v    t        |       dk(  r	d| d    dS dj                  | d d       d| d    z   }d| dS )	Nrl   zCCerto, per cancellare la prenotazione mi serve ancora questo dato: r   r%  r&  r'  z e il zECerto, per cancellare la prenotazione mi servono ancora questi dati: r8  r+  s     r;   r]  r]  2  s`    
>aTUcdeUfTgghiiYY~cr*+~b7I6J.KKFRSYRZZ[\\r=   c                    t        | d         }| j                  d      xs d}t        |      }| j                  d      r
| d| d    }d| d| dS )	Nr   r   indicator    alle z4Non riesco a trovare una prenotazione attiva a nome  per o. Se vuoi, prova a indicarmi anche l'orario o il numero di telefono usato per prenotare, cosi controllo meglio.)rp  rO  format_date_italian)r3  booking_dater   	slot_texts       r;   r_  r_  9  sr    !%(:";<LIIo.<*M#L1Iyy kl(;'<=	
>}oUS\R] ^x 	xr=   c                N    t        |       }|syt        |      dk  r|S d|dd   S )Nztelefono non disponibilern   z...)r  r   r  s     r;   r?  r?  E  s6    #E*F)
6{ar=   c                :   t        |d         }|j                  d      xs d}| d d D cg c]@  }|j                  j                  d       dt	        |j
                  j                         dB }}dj                  |      }d	| d
t        |       d| dS c c}w )Nr   r   rX  rn   r9   (); z#Ho trovato piu prenotazioni a nome rZ  z. Per capire qual e quella giusta da cancellare, puoi indicarmi l'orario esatto oppure il numero di telefono usato per prenotare? Opzioni trovate: r%  )	rp  rO  r   rw  r?  customerphoner   r\  )r  r3  r]  r   r4  optionsoptions_texts          r;   r`  r`  N  s    !%(:";<LIIo.<*M &bq> !!**73
4B7KKL`L`LfLf7g6hhijG  99W%L
-m_EBUVbBcAd e(>	,s   ABc                x    t        t        | d               }t        | d         }d| d    dt        ||       dS )Nr   r   z/Perfetto, ho cancellato la prenotazione a nome r   rZ  r%  )rp  r   format_booking_slot)snapshotr]  r   s      r;   ra  ra  ]  sS    !#h/A&B"CDLXl+,J
9(?:S9T U"<<=Q	@r=   c                   t        |d         }t        t              j                  t	        t        j
                              j                  t        t        j                  t        j                  k(        j                  t        j                  | k(  t        j                  |k(  t        j                  j                  t                    j!                  t        j"                  t        j                        }t%        |j'                  |      j)                               }t+        |j-                  d      xs d      j/                         }|r;|D cg c]0  }|j
                  "t1        |j
                  j2                  |      r|2 }}t5        |j-                  d            }|rh|D cg c]]  }|j
                  Ot5        |j
                  j6                        0t5        |j
                  j6                        j9                  |      r|_ }}|j-                  d      }	|	rKt;        t+        |	            r7|D cg c],  }|j"                  j=                  d      t+        |	      k(  s+|. }}|S c c}w c c}w c c}w )Nr   r   r5   r   r   r9  )rp  r   r   rg  r   re  r   r   r  r   r   r   r   r@  r  ACTIVE_RESERVATION_STATUSESr  r   r  r  uniquer   rO  r7   r  r  r  rf  endswithr  rw  )
r   r3  r   r   r   r  r  r4  lookup_phonelookup_times
             r;   r^  r^  f  s   %e,>&?@{	K001	2	h//8;;>	?	  H,((,<<""#>?


 
+((+..	9 	 bjj&--/0Jeii06B7==?K  *
##/4L[MaMaMfMfhs4t 

 
 *%))4D*EFL  *
##/&{';';'A'ABN&{';';'A'ABKKLY	 

 
 ))L)K)#k*:;+5
'9O9O9X9XY`9aehiteu9uK

 
 -


s   5I,(A"I17,I6$I6c                   t        j                  t              j                         }t	        t
              j                  t        t
        j                              j                  t        t
        j                  t        j                  k(        j                  t
        j                  | k(  t
        j                  j!                  t"              t
        j$                  |k\        j'                  t
        j$                  t
        j(                  t
        j                        }t+        |j-                  |      j/                               }t1        |j3                  d            }t1        |      }|ri|D 	cg c]]  }	|	j                  Ot1        |	j                  j4                        0t1        |	j                  j4                        j7                  |      r|	_ }}	nn|rl|D 	cg c]]  }	|	j                  Ot1        |	j                  j4                        0t1        |	j                  j4                        j7                  |      r|	_ }
}	|
r|
}t9        |j3                  d      xs d      j;                         }|r;|D 	cg c]0  }	|	j                  "t=        |	j                  j>                  |      r|	2 }}	|j3                  d      }|rGtA        t9        |            r3tC        t9        |            }|D 	cg c]  }	|	j$                  |k(  s|	 }}	|j3                  d      }|rKtE        t9        |            r7|D 	cg c],  }	|	j(                  jG                  d      t9        |      k(  s+|	. }}	|S c c}	w c c}	w c c}	w c c}	w c c}	w )Nr   r   r5   r  r  r9  )$r   r  r  r   r   r   rg  r   re  r   r   r  r   r   r   r@  r  rm  r   r  r   r  r  rn  r  rO  rf  ro  r   r7   r  r  r  rp  r  rw  )r   r3  r1  r   today_localr   r  rp  sender_lookup_phoner4  sender_matchesr  lookup_dateparsed_lookup_daterq  s                  r;   "find_reservations_for_modificationrx    s    ,,w',,.K{	K001	2	h//8;;>	?	  H,""#>?((K7


 
+..0F0F	W 	 bjj&--/0J)%))4D*EFL0>  *
##/&{';';'A'ABN&{';';'A'ABKKLY	 

 
 
  *
##/&{';';'A'ABN&{';';'A'ABKKL_`	 
 
 'Jeii06B7==?K  *
##/4L[MaMaMfMfhs4t 

 
 ))56K([)9:+C,<=5?vk;C_C_cuCukv
v))/0K)#k*:;5?  Ak;CYCYCbCbcjCkors~oCk  A
  AG


 w As,   2A"M(A"M-75M2-M7M73,M< M<c                   t        j                  t              j                         }t	        |      }|sg S t        t              j                  t        t        j                              j                  t        t        j                  t        j                  k(        j                  t        j                  | k(  t        j                   j#                  t$              t        j&                  |k\        j)                  t        j&                  t        j*                  t        j                        }t-        |j/                  |      j1                               }|D cg c]]  }|j                  Ot	        |j                  j2                        0t	        |j                  j2                        j5                  |      r|_ c}S c c}w r   )r   r  r  r   r  r   r   rg  r   re  r   r   r  r   r   r   r@  r  rm  r   r  r   r  r  rn  rf  ro  )r   r1  r   rs  rt  r   r  r4  s           r;   rG  rG    sI   ,,w',,.K0>	 	{	K001	2	h//8;;>	?	  H,""#>?((K7


 
+..0F0F	W 	 bjj&--/0J &+";#7#7#=#=>J";#7#7#=#=>GGH[\	 	  s   A"F?c           	        | s	 yt        |       dk(  rl| d   }|j                  |j                  j                  nd}d| dt        |j                  |j
                  j                  d             d|j                   d	S | d d
 D cg c]A  }t        |j                  |j
                  j                  d             d|j                   dC }}dj                  |      }dt        |        d| dS c c}w )NztAl momento non vedo prenotazioni attive associate a questo numero. Se vuoi, posso aiutarti subito a farne una nuova.rl   r   teu%   Sì, risulta una prenotazione a nome rZ  r9  r&  zD persone. Se vuoi, posso anche aiutarti a modificarla o cancellarla.rn   z personerd  u   Sì, risultano z0 prenotazioni attive associate a questo numero: z:. Se vuoi, posso aiutarti a modificarne o cancellarne una.)	r   re  r  rj  r   r   rw  r   r   )r  r4  r   rg  rh  s        r;   rH  rH    s/   @	

 <A"1o5@5I5I5U,,11[_3M?%";#?#?AWAWA`A`ahAijkkm!!""fh	
 (+
  #;#?#?AWAWA`A`ahAijkkm!!"(,G  99W%L
#l+,,\]i\j kC 	Cs   AC1c           	         | j                   | j                   j                  nd}d| dt        | j                  | j                  j                  d             d| j                   dS )Nclientez"Ho trovato la prenotazione a nome rZ  r9  r&  zR persone. Dimmi pure cosa desideri modificare: giorno, orario o numero di persone.re  r  rj  r   r   rw  r   r4  r   s     r;   rW  rW    sl    1<1E1E1QK((--W`M
,]O5{;;[=S=S=\=\]d=ef
ggi
p	rr=   c                &   | j                  d      }| j                  d      xs d}|rht        t        |            rTt        t	        t        |                  }| j                  d      }|rt        t        |            r| d| }d| d| dS 	 y	)
Nr  r   rX  r  rY  z?Non riesco a trovare una prenotazione attiva da modificare per z il r[  zNon riesco a trovare prenotazioni attive associate a questo numero. Se vuoi fare una nuova prenotazione, scrivimi pure giorno, orario e numero di persone.)rO  r  r   r\  rp  r  )r3  rv  r   r^  rq  s        r;   "build_modification_not_found_replyr    s    ))56KIIo.<*M([)9:'s;7G(HI	ii 34-c+.>?$+VK=9IMm_\`aj`k l| |	
	<r=   c           
        | d d D cg c]d  }t        |j                         d|j                  j                  d       dt	        |j
                  r|j
                  j                  nd        df }}dj                  |      }d| dS c c}w )	Nrn   rY  r9  rb  rc  rd  zHo trovato piu prenotazioni attive da modificare. Per capire qual e quella giusta, indicami il giorno esatto oppure l'orario o il numero di telefono usato per prenotare. Opzioni trovate: r%  )r\  r   r   rw  r?  re  rf  r   )r  r4  rg  rh  s       r;   'build_modification_disambiguation_replyr  #  s     &bq>
  #;#?#?@AH^H^HgHghoHpGq r$;CWCW[%9%9%?%?]abccdfG  99W%L	(>	,s   A)B
c           	         | j                   | j                   j                  nd}d| dt        | j                  | j                  j                  d             d| j                   dS )Nr}  z/Perfetto, ho aggiornato la prenotazione a nome z: r9  r&  z	 persone.r~  r  s     r;    build_modification_success_replyr  3  sj    1<1E1E1QK((--W`M
9-{;;[=S=S=\=\]d=ef
ggi
i	)r=   r>  c           
         t        | |j                  d            }|rd| nd}|sd| | d| d| dS dj                  d	 |D              }d| | d| d| d
| d
S )Nr9   in r5   zJMi dispiace, al momento non ho disponibilita per la modifica richiesta su , per z persone con turno da z; minuti. Se vuoi, indicami un altro orario o un'altra data.r&  c              3  >   K   | ]  }|j                  d         ywr9  Nrw  r  slots     r;   r  z7build_modification_unavailable_reply.<locals>.<genexpr>M       !RT$--"8!R   z& minuti. Posso proporti questi orari: z&. Scrivimi pure quello che preferisci.)rj  rw  r   )	r   r   r   r5  r  r<  r^  	area_textalternatives_texts	            r;   $build_modification_unavailable_replyr  <  s     $$4j6I6I'6RSI+9$~&'rIXYbXcdmcnntu{t|  }S  []	

 		!R\!RR
TU^T_`i_jjpqwpx  yO
BCTBU V/	/r=   c                
   j                  d      }|K	 t        t        |      |      }|j                  | k(  r|j                  t
        v r|S j                  dd        t        | i ||      }t        fddD              }	|	st        |      dk(  r|d   S |	st        |      dkD  r	 yt        | ||      }
|
st              S t        |
      dkD  rt        |
      S |
d   S # t        $ r j                  dd        Y w xY w)Nr2  )r   r3  r1  r   c              3  @   K   | ]  }j                  |        y wr   r  )r  fieldr3  s     r;   r  z.resolve_modification_target.<locals>.<genexpr>o  s"       			%r  )r  r  r   r   rl   r   zHo trovato piu prenotazioni attive associate a questo numero. Per capire quale vuoi modificare, dimmi il giorno della prenotazione e, se serve, anche l'orario.)rO  r$   rr  r   r@  rm  r  r   rx  r  r   r  r  )r   r1  r0  r/  r3  r   r2  r4  sender_candidateshas_lookup_detailsr  s       `      r;   rT  rT  U  s8    "II&=>(	505J1KRPK ##x/K4F4FJe4e""II-t4:!	  h  #&7"8A"= ###&7"81"<p	

 4!	J 1%88
:6zBBa=G  	5II-t4	5s   C$ $DDc           
     ^   t        | |j                        }|*|dk  r%| j                  dd        | j                  dd        y||| d<   | j                  dd        i }| j                  d      r1t	        t        | d               rt        t        | d               |d<   | j                  d      r1t        t        | d               rt        t        | d               |d	<   |||d
<   | j                  d      }d
|vr|dvrt        |      |d
<   |sy |j                  d|j                        }|j                  d	|j                        }t        |j                  d
|j                              }||j                  k7  xs  ||j                  k7  xs ||j                  k7  }	|	s| j                  d      |j                  j                         k(  r| j                  dd        | j                  d      |j                  j                  d      k(  r| j                  dd        | j                  d      |j                  k(  r| j                  dd        y |	rt        |j                  ||||j                   |j"                  |j$                  |      }
|
sbt'        |j                  ||||j                   |j"                  |j$                  |      }t)        ||||j                   ||j"                        dfS t+        |j$                  t-        di ||      }| j/                          t1        |      dfS )Nrl   r  r  )zVVa bene, ma il numero di persone deve restare almeno 1. Indicami il totale aggiornato.Fr  r  r   r  r   r   r  r9  r6  )r   r   r8  r   r5  r   r7  r   )r   r   r   r5  r  r<  FTr   )resolve_modified_guest_countr   r  rO  r  r   rp  r  rq  rr  r   r   	isoformatrw  check_availabilityr   r5  r   r   rv  r  r%   r   clearr  )r3  r4  r   new_guest_countpayload_datar  candidate_datecandidate_timecandidate_guestsactual_changes	availabler  updateds                r;   rV  rV    s#    35+:L:LMO"':		,%		-&p"-l		&-&(Lyy'(->s5I_C`?a-b+9#eDZ>[:\+]'(yy!"'9#eDT>U:V'W%4S?O9P5Q%R\""!0X#78|#(:-(O!$%7!8X!%%&8+:V:VWN!%%lK4J4JKN<++Hk6H6HIJ+666 	2[333	2{111 
 99+,0L0L0V0V0XXII,d399%&+*@*@*I*I'*RRII&-99\"k&8&88IIlD)& ))+%#(99'77#.>>	
	 4$--!/-'!,!=!= + ; ;'2~~	L 5%3-+%0%A%A!-#.#>#> 
 
 !)L)
G
 
KKM,W5t<<r=   c                    | j                  d      dvrt        | d         S | j                  d      }|dvr | j                  dd        |t        |      z   S y )Nr  r  r  r  )rO  rr  r  )r3  current_guestsr  s      r;   r  r    sZ    yym35&''))M*K*$		-&K 000r=   )r   r7  c           
         t        | |||||||      }|j                  r|j                  S t        |j                        S )Nr6  )ro  r   r   r   r   )	r   r   r   r   r5  r   r7  r   r  s	            r;   r  r    sN     /))'5	L &&666--..r=   c                   t               }g }	t        ||      }
t        t        t        t        z   t              D ]  }dD ]  }|
t        ||z        z   }|j                         |k7  r)|j                         j                  dd      }|j                  d      }||v r`|j                  |       t        | |||||||      s|	j                  |       t        |	      t        k\  s|	c c S   |	S )N)r'  rl   minutesr   r   microsecondr9  r6  )r*  r   r  ALTERNATIVE_STEP_MINUTESALTERNATIVE_WINDOW_MINUTESr   r   r   r  rw  r  r  r!  r   ALTERNATIVE_LIMIT)r   r   r8  r   r5  r   r7  r   seensuggestionsrequested_atstep	directioncandidate_atr  slot_keys                   r;   rv  rv    s    UD K$%5~FL.0JMe0eg  A '  	'I')D9<L*MML  "&66$$&..aQ.GD}}W-H4HHX!!!1!1 /'=	 ""4({#'88&&-	''2 r=   c                    t        t        j                  d | D                    }|syt        |      dk(  r|d   S t        |      dk(  r|d    d|d    S dj	                  |d d       d|d    z   S )	Nc              3  d   K   | ](  }|s|j                         s|j                          * y wr   )r7   )r  r  s     r;   r  z$format_room_names.<locals>.<genexpr>4  s$     %ctTVZV`V`Vbdjjl%cs   000r5   rl   r   rm   r(  r&  r'  )r  r  fromkeysr   r   )
room_namesunique_namess     r;   format_room_namesr  3  s    %cz%ccdL
<AA
<Aq/"#l1o%67799\#2&'CR0@/A*BBBr=   c                   | j                   6| j                   j                   | j                   j                  j                  S | j                  6| j                  j                   | j                  j                  j                  S y r   )assigned_tableroomr  assigned_combination)r4  s    r;   ru  ru  >  so    !!-+2L2L2Q2Q2]))..333''38X8X8]8]8i//44999r=   c                l    t        | d         }t        |      }dt        || d          d| d    d| dS )Nr   zHo disponibilita per r   r  r   z persone, nelle aree z?. Dimmi pure dove preferisci stare e poi te la confermo subito.)rp  r  rj  )r3  r  r]  
rooms_texts       r;   r{  r{  F  sZ    !%(:";<L":.J
 3L%BU VW XX4ZL AH	Hr=   c          	         t        | d         }t        |      }t        |      dk(  rdt        || d          d| d| d| d    d		S dt        || d          d| d
| dS )Nr   rl   zPer r   z non ho disponibilita in z, ma posso proporti rZ  r   zG persone. Se per te va bene, rispondi pure CONFERMO e la blocco subito.z(, ma posso ancora proporti queste aree: z. Dimmi pure quale preferisci.)rp  r  r   rj  )r3  r<  r=  r]  available_rooms_texts        r;   rz  rz  P  s     "%(:";<L,-AB
 A%&|U<5HIJJcdrcs t!!5 6eE(O;L MLL	
 "<|1DEFF_`n_o p11E0F G'	'r=   c           	     t    t        | d         }|rd| nd}d| dt        || d          d| d    d	| d
    d	S )Nr   r  r5   zHo trovato disponibilitarZ  r   r  r   z, persone. La durata prevista del turno e di r5  zF minuti. Se per te va bene, rispondi pure CONFERMO e la blocco subito.rp  rj  )r3  r   r]  	room_texts       r;   r|  r|  e  so    !%(:";<L&/$yk"RI
"9+U3F|UZ[gUh3i2j kXKERdLeKf gH	Hr=   c                  t        | d         }|rdnd}|rd| nd}|s#| dt        || d          | d| d	    d
| d    d	S dj                  d |D              }| dt        || d          | d| d	    d
| d    d| dS )Nr   z3Mi dispiace, quella disponibilita non e piu libera.z2Mi dispiace, in quell'orario non ho disponibilita.r  r5   z Per r   z, con turno da r5  z
 minuti e r   z9 persone, puoi indicarmi un altro orario o un'altra data.r&  c              3  >   K   | ]  }|j                  d         ywr  r  r  s     r;   r  z*build_unavailable_reply.<locals>.<genexpr>  r  r  z- persone, posso proporti queste alternative: z%. Dimmi pure l'orario che preferisci.)rp  rj  r   )r3  r  r;  r<  r]  prefixr  r  s           r;   rx  rx  o  s     "%(:";<LFPB  WKF+9$~&'rIhe/eL>QRST]S^ _!"456jx@Q R>>	
 		!R\!RR(%+L%:MNOPY{ [012*U8_<M N..?-@@e	gr=   c                P    t        | d         }dt        || d          d| d    dS )Nr   zfMi dispiace, in questo momento non riesco ancora a verificare la disponibilita in modo affidabile per r   z, con r   z persone. Sto ancora aggiornando la configurazione della sala. Se vuoi, puoi riprovare piu tardi oppure indicarmi un altro orario e lo tengo come riferimento.r  )r3  r]  s     r;   rn  rn    sB    !%(:";<L
p|U<-@A
B&xHY Z7	7r=   c                    t        | d         }| j                  d      xs d}|rd| nd}d| dt        || d          | d	| d
    dS )Nr   r   r}  r  r5   z.Perfetto, la prenotazione e confermata a nome rZ  r   r&  r   zZ persone. Se in seguito vuoi modificarla, puoi rispondere direttamente a questo messaggio.)rp  rO  rj  )r3  r   r]  r   r  s        r;   rt  rt    sn    !%(:";<LIIo.;)M&/$yk"RI
8u|U<-@A
B9+R?
u	wr=   c                "    t        |        d| S )NrY  )r\  )r]  
hhmm_values     r;   rj  rj    s    !,/0zlCCr=   c                    t         | j                             d| j                   dt        | j                  dz
      d| j
                   S )Nr   rl   )WEEKDAY_NAMESweekdaydayMONTH_NAMESmonthyearr  s    r;   r\  r\    sG    EMMO,-Quyyk;u{{UV;W:XXYZ_ZdZdYeffr=   c                n    | sy| j                         j                         dv ryt        d | D              S )NF>   unknownsconosciutoc              3  <   K   | ]  }|j                           y wr   )isalphar  s     r;   r  z%is_meaningful_name.<locals>.<genexpr>  s     :yy  ":rI  )r7   r  r  r  s    r;   rP  rP    s4    {{}#==:E:::r=   c                ,    t        j                  |       S r   )r   fromisoformatr  s    r;   rp  rp        e$$r=   c                ,    t        j                  |       S r   )r   r  r  s    r;   rq  rq    r  r=   c                N    	 t        j                  |        y# t        $ r Y yw xY wr  )r   r  
ValueErrorr  s    r;   r  r    .    5!       	$$c                N    	 t        j                  |        y# t        $ r Y yw xY wr  )r   r  r  r  s    r;   r  r    r  r  c                   t        |t        | d         j                         t        | d         j                         t        | d         t	        | d         t        | d         t        | d         t        j                  t        j                  | j                  d      | j                  d      	      }t        ||      S )
Nr   r   r   r   r5  r   r   r   )r   r   r   r   r   r5  r   r@  r  r   r   )r   r   r7   rp  rq  rr  r   r.  r   rR   rO  create_reservation_if_available)r3  r   r   payloads       r;   rs  rs    s    %017795!12399;'.@(AB"5#67U#5675?# ** ))ii 		"34G +7B77r=   c                J   ddl m}m}m} d }	 |j	                         5   || |      }t        | j                  |j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  
      }|j!                  |       |j#                           |||j                  |       |j#                          t%        | j                  | j                  |      }t'        | j                  | j                  |      }	t)        || j                  |||	      }
|
t*        ddlm}  |||
|       |j#                          |j                  }d d d        |y  |||      S # 1 sw Y   xY w# t*        $ r Y y w xY w)Nr   )append_status_historyfind_or_create_customerr$   r  r  )assign_room_candidate) app.services.reservation_servicer  r  r$   begin_nestedr   r   r   r   r   r5  r   r@  r  r   r   r  rB  r   r    r!   r   app.services.assignmentr  )r  r   r  r  r$   rN  re  r4  r  r   r  r  s               r;   r  r    s}   ww!%N&__ #	,.w;H% ))$KK!(!9!9"--!(!9!9~~~~~~mm ' 7 7K FF;HHJ!+{/A/A2FHHJ3G4L4LgN^N^`bcI!;G<L<LgNeNegi!j:  #5I  22E!+y"=HHJ(^^NG#	,N !."55U#	, #	,H ( s)   F EF
6F 
FF 	F"!F"c           
        t               }t               }||j                  nd ||j                  ni |d|d|d   i}t	        | |      }	 t        j                  |j                        5 }|j                  |j                  j                  d       dt               dd	t        d
d|d
gd      }|j                          |j                         }	d d d        t#        	t$              r|	j'                  d      nd }
d }t#        |	t$              rj|	j'                  d      }t#        |t(              rI|rG|d   }t#        |t$              r2|j'                  d      }t#        |t$              r|j'                  d      }t#        |t*              r|j-                         st!        | |      t+        |
xs d      fS 	 t/        |      }t0        j3                  |      }t;        || |      }|t+        |
xs d      fS # 1 sw Y   #xY w# t        $ r t!        | |      d fcY S w xY w# t        j4                  t6        t8        f$ r t!        | |      }Y tw xY w)N)r@  r3  r0  todaycurrent_dater*  session_payload)timeout/z/llm/openai/chat/completionsr   system)rolecontentuser)temperaturemessages)r9   jsonmodelchoicesmessager  r5   )r   r&   r@  r3  build_booking_extraction_prompthttpxClientassistant_timeout_secondspostassistant_api_base_urlrstripr<    BOOKING_EXTRACTION_SYSTEM_PROMPTraise_for_statusr  	Exceptionapply_fallback_extractionrU  r  rO  r  r   r7   parse_json_objectr   model_validateJSONDecodeErrorr   r  apply_deterministic_overrides)r*  r/  r0  r8   temporal_contextr  promptclientresponser  r  r  r  first_choicer  r   r  enricheds                     r;   rE  rE  	  sA    ~H+-$+$7'..T")"52" 	
 	!.1O -=ZijFG\\("D"DE 	&{{2299#>??[\24#$!)6VW!'F;! # 
H %%'mmoG	&" %/w$=GKK 4EG'4 ++i(gt$"1:L,-&**95gt,%kk)4Ggs#7==?(@#ekrBRRRG&w/
&55jA
 -ZPHS"%%%M	& 	&  G(@$FFG(   /:> G.}gF
Gs=    H .A(G7H 9 H! 7H<H HH!*IIa  
Sei un parser rigoroso per prenotazioni di un locale.
Restituisci SOLO JSON valido, senza testo aggiuntivo.
Non inventare mai dati mancanti.
Se un dato non e espresso in modo chiaro, restituisci null.
Interpreta una conferma solo se il cliente conferma esplicitamente una proposta gia presente nel contesto.
Schema richiesto:
{
  "booking_related": boolean,
  "intent": "booking_request" | "confirm" | "decline" | "cancel" | "modify" | "info" | "other",
  "reservation_date": "YYYY-MM-DD" | null,
  "start_time": "HH:MM" | null,
  "guests": integer | null,
  "customer_name": string | null,
  "customer_phone": string | null,
  "area_preference": string | null,
  "notes": string | null,
  "confidence": "high" | "medium" | "low"
}
Regole:
- booking_related=true solo se il messaggio riguarda una prenotazione, conferma, modifica o disponibilita.
- intent=modify se il cliente vuole cambiare una prenotazione gia esistente, per esempio giorno, orario o numero di persone.
- Se il cliente prenota a nome di un'altra persona, customer_name deve essere il nome della prenotazione, anche se diverso dal mittente.
- Interpreta anche errori ortografici comuni del cliente se il significato resta chiaro.
- Usa sempre il contesto temporale fornito dal sistema per interpretare riferimenti come oggi, domani, dopodomani, stasera e prossima settimana.
- Se l'orario non e abbastanza preciso, usa null.
- Se il nome non e esplicito, usa null.
c                X    dt        j                  |d       d| j                          S )NzContesto sessione JSON:
T)ensure_asciiz

Messaggio cliente:
)r  dumpsr7   r  s     r;   r  r  b  s4    #::oD9
: ; 
!	#r=   c                N   | j                         }|j                  d      r.t        j                  dd|      }t        j                  dd|      }|j	                  d      }|j                  d      }|dk(  s
|dk(  s||k  rt        d      t        j                  |||d	z          S )
Nz```z^```(?:json)?\s*r5   z\s*```${}r'  zJSON object non trovatorl   )	r7   r   r   r   findrfindr  r  loads)raw_contentr  r  ends       r;   r
  r
  k  s    !G% &&,b':&&R1LLE
--
C{cRi3%<233::gecAg.//r=   c                   t        |       }t        |       }t        |       }t        |       xs t	        |      xs |d uxs
 |d uxs |d u}d}t        | t              rd}nAt        | t              rd}n.t        | t              rd}nt        | t              r|dnd}n|rd}t        |||||t        |       t        |       d      S )	Nr   r  r  r  r  booking_requestr   )r   r   r   r   r   r   r   r   )r  r  r  r+  rD  r#  r  r  r  r  r  r   r  r  )r*  r/  extracted_dateextracted_timeextracted_guestsr   r   s          r;   r	  r	  y  s    *=9N*=9N3MB$]3 	(,W5	(%	( %	( 4'  F%m5JK	'7L	M	)-9I	J	)-9I	J%17H	"''!+M:-m<	 	r=   c                   t        ||      }| j                         }|d   s|j                  r|j                  |d<   |d   s|j                  r|j                  |d<   |d   |j                  |j                  |d<   |d   s|j
                  r|j
                  |d<   |d   s|j                  r|j                  |d<   |d   dk(  r|j                  dk7  r|j                  |d<   |d   s|j                  rd	|d<   t        j                  |      S )
Nr   r   r   r   r   r   r   r   T)r	  
model_dumpr   r   r   r   r   r   r   r   r  )r  r*  r/  fallbackr  s        r;   r  r    s   
 )@H##%G%&8+D+D&.&?&?"#< X%8%8 ( 3 3x X__%@$OO?#(>(>#+#9#9 #$)@)@$,$;$; !xG#7(B$OO$%(*B*B%)!"++G44r=   c                    t        j                  d| xs d      j                  dd      j                  d      }|j	                         S )NNFKDr5   asciiignore)unicodedata	normalizeencodedecoder  r   s     r;   r   r     s@    &&vu{;BB7HU\\]deJ  r=   c                   t        |       }t        j                  t              j	                  dd      }g d}|D ]  \  }}t        j                  ||t
        j                        }|s.|dk(  r|t        d      z   }n?t        |j                  d            }|`|dk(  rt        |	      nt        |      }	||	z   }|j                  d
z  }
|
r|t        d
|
z
        z  }|j	                  dd      c S  y )Nr   r  ))zf\b(?:tra|fra)\s+(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,3})(?:\s+|')or[ae]\br  )zc\b(?:tra|fra)\s+(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,3})\s+minut[oi]\br  )z#\b(?:tra|fra)\s+mezz(?:'|a\s+)ora\b	half_hourr0     r  rl   r  r  ro   )r   r   r  r  r  r   r&  
IGNORECASEr   parse_small_number_tokengroupminute)r*  r   	now_localpatternsr1  unitmatchtargetamountdeltaminute_remainders              r;   extract_relative_datetimer>    s    (7JW%--QA-FI'H
 " 7		':r}}=;2!66F-ekk!n=F~/3wIF+IV\D]E&F!==1,i,<(<==F~~QA~66#7& r=   c                   t        |       }dddddddd}t        t        j                  d	|            }|st	        |      }t        |      D ]  \  }t        fd
t        D        d       }|"|j                  |      }| y ||j                         z
  dz  }	|t        d|dz
        | }
t        d |
D              r|	dk(  rd}	|t        |	      z   j                         c S  y |d   }|j                  d      }|j                  |      }|y ||j                         z
  dz  }	|t        d|j                         dz
        |j                          }d|v r|	dk(  rd}	|t        |	      z   j                         S )Nr   rl   rm   r)   rn   ro   rp   r   z^\b(?:quest[oa]\s+|prossim[oa]\s+)?(lunedi|martedi|mercoledi|giovedi|venerdi|sabato|domenica)\bc              3  @   K   | ]  }t        |d       s|  yw)r  r   Nr  )r  r  r:   s     r;   r  z'extract_weekday_date.<locals>.<genexpr>  s     kW9J5RYei9jks   rq   c              3  8   K   | ]  }t        |d d        yw)prossimor  r   Nr  )r  r  s     r;   r  z'extract_weekday_date.<locals>.<genexpr>  s     eV$VZ4HHes   daysr'   prossim)r   r  r   finditerr   r   nextr  rO  r  r   r  r   r  r4  r  )r*  rs  r   weekday_aliasesmatchestokensr   matched_weekdaytarget_weekday
days_aheadprefix_tokensr9  weekday_tokenr  r:   s                 @r;   extract_weekday_daterP    s   (7JO 
m	
G &z2%f- 	JLE5"kkO &,00AN%(;+>+>+@@AEJ"3q%!)#4u=MeWdeejtxyjy
)"<<GGII	J AJEKKNM$((7N ;#6#6#88A=JAu{{}r12U[[]CFFzQ
)44??AAr=   c                   t        |       }t        j                  t              j	                         }t        |       }||j	                         j                         S t        |dd      r|t        d      z   j                         S t        |dd      r|t        d      z   j                         S t        |dd      r|j                         S t        |d	d      r|j                         S t        | |      }|r|S t        j                  d
|       }|r7|j                  d       d|j                  d       d|j                  d       S t        j                  d|       }|rt        |j                  d            }t        |j                  d            }|j                  d      }	|	|j                  }
n(t!        |	      dk(  rdt        |	      z   }
nt        |	      }
	 t	        |
||      }|	0||k  r+	 t	        |j                  dz   ||      }|j                         S |j                         S y # t"        $ r Y y w xY w# t"        $ r Y y w xY w)Nrh   r  r   rm   rC  rg   rl   )rj   rk   ri   z\b(20\d{2})-(\d{2})-(\d{2})\b-r)   z&\b(\d{1,2})/(\d{1,2})(?:/(\d{2,4}))?\bi  )r   r   r  r  r   r>  r  r  r   r  rP  r   r&  r4  rr  r  r   r  )r*  rF  rs  relative_datetimeweekday_date	iso_matchslash_match	day_valuemonth_value
year_valuer  resolveds               r;   r  r  	  s7   %m4G,,w',,.K1-@$ %%'1133#G\TJiQ//::<<#GXFiQ//::<<'1KW[\$$&&#GVtD$$&&'{CL		:MJI//!$%Qyq'9&:!IOOA<N;OPP))E}UK))!,-	+++A./ &&q)
##D_!#j/)Dz?D	D+y9H (["8 0 01 4k9M !!##x!!##  		
  s$   $H4 9I 4	I ?I 	IIc                   t        |       }||j                  d      S t        j                  d|       }|r=t	        |j                  d            }t	        |j                  d            }|dd|dS t        |       }t        j                  d|t        j                        }d }|rt	        |j                  d            }n`t        |      }t        |d d       D ]D  \  }}	t        |	d	d
      s|	dk(  s||dz      }
t        j                  d|
      s9t	        |
      } n |y |}|dk  rt        |dd
      r|dk(  rdn|dz   }|dk  ry |ddS )Nr9  z!\b([01]?\d|2[0-3])[:.]([0-5]\d)\brl   rm   02dr  z\balle\s+([01]?\d|2[0-3])\br'  aller  r   orez([01]?\d|2[0-3])r'   )serarj   
pomeriggioz:00)r>  rw  r   r&  rr  r4  r   r2  r   r   r  	fullmatchr  )r*  rS  r9  
hour_valueminute_valuer   simple_matchrJ  r   r:   
next_tokenrF  s               r;   r  r  =	  sg   1-@$ ))'22II:MJEQ(
5;;q>*S!<"455%m4J99;ZWL!J++A./
&z2%fSbk2 	LE5 $?5E>#EAI.
<< 3Z@!$ZJ	 GR<WFgswx%+Rb
RS!!r=   c                    g d}|D ]J  }t        j                  || t         j                        }|s+t        |j	                  d            }|H|c S  y )N)zR\bsiamo in (un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,3})\bzq\bper (un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,3}) (?:persone|persona|coperti|coperto)\bzm\b(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,3}) (?:persone|persona|coperti|coperto)\bz[\bin (un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,3})(?=\s*[?.!,]|$)\brl   r   r&  r2  r3  r4  )r*  r7  r1  r9  r;  s        r;   r  r  `	  sU    H  		'="--@-ekk!n=F! r=   c                    | j                         j                         }|j                         rt        |      S t        j                  |      S r   )r7   r  r  rr  ITALIAN_SMALL_NUMBERSrO  )r   cleaneds     r;   r3  r3  p	  s;    kkm$$&G7| $$W--r=   c                    g d}|D ]P  \  }}t        j                  || t         j                        }|s.t        |j	                  d            }|K||z  c S  y )N))z\baggiung(?:i|ere)?\s+(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,2})\s+(?:persona|persone|coperto|coperti)\brl   )z\baument(?:a|are)?\s+(?:a\s+)?(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,2})\s+(?:persona|persone|coperto|coperti)\brl   )z\btogli(?:ere)?\s+(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,2})\s+(?:persona|persone|coperto|coperti)\br'  )z\briduc(?:i|e|ere)?\s+(?:di\s+)?(un|una|uno|due|tre|quattro|cinque|sei|sette|otto|nove|dieci|\d{1,2})\s+(?:persona|persone|coperto|coperti)\br'  rl   rg  )r*  r7  r1  r  r9  r;  s         r;   r  r  w	  sc    'H ' &		'="--@)%++a.9I%%& r=   c                    g d}|D ]n  }t        j                  || t         j                        }|s+t        j                  dd|j	                  d            j                  d      }t        |      sl|c S  y )N)uo   \ba\s+nome\s+di\s+([A-Za-zÀ-ÿ][A-Za-zÀ-ÿ' .-]{1,80}?)(?=\s+(?:per|il|domani|oggi|dopodomani|alle)\b|[,.]|$)uj   \ba\s+nome\s+([A-Za-zÀ-ÿ][A-Za-zÀ-ÿ' .-]{1,80}?)(?=\s+(?:per|il|domani|oggi|dopodomani|alle)\b|[,.]|$)ur   \bper\s+conto\s+di\s+([A-Za-zÀ-ÿ][A-Za-zÀ-ÿ' .-]{1,80}?)(?=\s+(?:per|il|domani|oggi|dopodomani|alle)\b|[,.]|$)uf   \bnome\s+([A-Za-zÀ-ÿ][A-Za-zÀ-ÿ' .-]{1,80}?)(?=\s+(?:per|il|domani|oggi|dopodomani|alle)\b|[,.]|$)r   r   rl   z .,-)r   r&  r2  r   r4  r7   rP  )r*  r7  r1  r9  r  s        r;   r  r  	  sn    H  		'="--@FF63A7==fE	i( r=   c                    t        j                  d|       }|sy 	 t        |j                  d            S # t        $ r Y y w xY w)Nz(\+?\d[\d\s().-]{5,}\d)rl   )r   r&  r"   r4  r  )r*  r9  s     r;   r  r  	  sC    II0-@E'A77 s   5 	A A)r   zdict[str, str])r   rr  r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   r   r   )r:   r   r   r   r   floatr   r   )r  r   r  r   r   rn  r   r   )r  r   r  tuple[str, ...]r   rn  r   r   )r  r   r  r   r   rn  r   r   )r  r   r"  ro  r   rn  r   r   )r*  r   r   r   )r   r   r1  r   r0  r   r*  r   r   rr  r}  rr  r   zBookingAutomationResult | None)r  r   r   r   )r/  r   r*  r   r   r   )r3  dict | Noner   r   )r/  WhatsAppBookingSession | Noner   r   )r/  r   r  r   r*  r   r   r   )r   r   r   r   )r   r   r   r   )r  r   r  r   r   r   )
r1  r   r   rr  r   r   r/  rq  r   r   )r1  r   r   rr  r   r   r   rq  )r1  r   r   r   r   rq  )r/  r   r   None)r  rp  r   r  )r3  r  r  r   r   rr  )
r3  r  r*  r   r   rr  r   r   r   rr  )r   rr  r   r   r   r   r   rr  r5  rr  r   r   r7  r   r   r   r   r   )
r3  r  r  r   r*  r   r  r   r   rr  )r  r   r   r   )r  r   r*  r   r   r   )r3  r  r   r   )r  r   r   r   )r3  r  r   r   )r3  r  r   r   )r   r   )r3  r  r*  r   r   r   )r  list[Reservation]r3  r  r   r   )rk  zdict[str, object]r   r   )r   rr  r3  r  r   r   r   rs  )
r   rr  r3  r  r1  r   r   r   r   rs  )r   rr  r1  r   r   r   r   rs  )r  rs  r   r   )r4  r   r   r   )r  rs  r   r   )r   r   r   r   r   rr  r5  rr  r  
list[time]r<  r   r   r   )r   rr  r1  r   r0  r   r/  r   r3  r  r   r   r   zReservation | str)r3  r  r4  r   r   r   r   ztuple[str, bool] | None)r3  r  r  rr  r   r   )r   rr  r   r   r   r   r   rr  r5  rr  r   r   r7  r   r   r   r   r   )r   rr  r   r   r8  r   r   rr  r5  rr  r   r   r7  r   r   r   r   rt  )r  r   r   r   )r4  r   r   r   )r3  r  r  r   r   r   )r3  r  r<  r   r=  r   r   r   r   )r3  r  r   r   r   r   )F)
r3  r  r  rt  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   r   r   r   )r   r   r   r   )r3  r  r   rr  r   r   r   Reservation | None)r  r   r   r   r   ru  )r*  r   r/  rq  r0  r   r   z$tuple[BookingExtraction, str | None])r*  r   r  r  r   r   )r  r   r   r  )r*  r   r/  rq  r   r   )r  r   r*  r   r/  rq  r   r   )r*  r   r   zdatetime | None)r*  r   rs  r   r   r   )r*  r   r   r   )r*  r   r   r   )r   r   r   r   )
__future__r   dataclassesr   r   r   r   r   difflibr	   r  r   r+  zoneinfor
   r   fastapir   pydanticr   r   r   
sqlalchemyr   sqlalchemy.ormr   r   app.core.configr   app.models.bookingr   app.models.customerr   app.models.reservationr   r   r   app.models.roomr   app.models.tabler   app.schemas.reservationr   r   r  r   r   r   r   r    r!   app.services.contact_validationr"   r  r#   r$   r%   !app.services.time_context_servicer&   r  r  r  r  r  r  rY  rL  r  r  r<   r  r  r  rQ  rR  rJ  r6  compiler2  r2  r;  pendingr.  seatedrm  r  r  r'  r(  r%  ri  r  r  r   r   r   r  r   r   r   r   r   r   r  r  r  r  r#  r+  r  rI  rC  re  rD  rK  rX  rR  r  r  r  rJ  r?  r  rA  rM  rb  rc  ro  rZ  rQ  r[  rS  r  r  rk  rl  rj  rg  rm  rh  ri  rd  rf  rF  r=  r@  rB  rL  ry  r\  r]  r_  r?  r`  ra  r^  rx  rG  rH  rW  r  r  r  r  rT  rV  r  r  rv  r  ru  r{  rz  r|  rx  rn  rt  rj  r\  rP  rp  rq  r  r  rs  r  rE  r7   r  r  r
  r	  r  r   r>  rP  r  r  r  r3  r  r  r  r   r=   r;   <module>r     s	   " ! 4 4 #  	    ! 6 6  . ( 5 ( T T   " H  E k k B
=
!     * !:<Y Z !68M N ')@  BC`  B  dA  B   L   " $   _ 	  BJJprtrr  ABJJxz|  {H  {H  IBJJ4bmmDBJJRTVTaTabBJJ4bmmDBJJ)2==9BJJ#R]]3BJJ:BMMJ	( $ BJJ2BMMBBJJ6FBJJ!2==1BJJ,bmm<BJJ:BMMJBJJDbmmT$       ,  2:: EMM 
 
   _ I7H-H 
	 
 + + + F F F$	9 	03I9 HL G$ PT $ ae f LP  ]a ^SOO O 	O
 O O O $OdQS(?#!  
	&#!  
	&PA	" .2  		
 + :*"2$88 8 	8
 	8 
82-- - 	-
 - -  - '- 	- -`4$;$;!$; $; 	$;
 
$;N		
M
	]b&0
q^NH!;H]	'T;; ; 	;
 	; ;|6<&   "&  	
    	200 0 	0
 $0 0 	0 0fW=W= W= 		W=
 W=t	& #')-// / 	/
 / /  / '/ 	/ 
/B #')-(( ( 	(
 ( (  ( '( 	( (VC  $	
 	* 
 "& 
  	2Dg;%%8"06f8&8& +8& 	8&
 *8&v$6 
EG7 !<0 F5!55 +5 	54!
>0Bf-` "F .""r=   