o
    Uxi                    @   s>  d dl mZ d dlmZ d dl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mZmZmZ d dlmZmZmZ e
eZed	d
d0ddZd1ddZdd Zd1ddZdd Zed	d
dd Zed	d
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) Z&d*d+ Z'd,d- Z(d.d/ Z)dS )2    )shared_task)settings)timezone)ClientN)Senior)CallCallLog
CallPrompt)ConversationMemoryConversationInsightT)bindgeneral_checkinc              
   C   s  z&t jj|d}ddlm} |std dddW S z
|jj|dd	}W n |jy?   td
| d ddd Y W S w d}	|rbz
tjj|dd	}	W n tjya   t	d| d Y nw |	sztjjddd}	t
d|	j  W n tjy   t
d d}	Y nw tjj||||	|dd}
tjj|
dd|j d|j |||dd t|||	}||
_|
  tjj|
dd|j t||dd t
d|j dt| d t|
|}|r||
_d|
_d |
_|
  tjj|
d!d"| d#|id t
d$|j  d%|
j|d&W S d'|
_|
  tjj|
d(d)dd*id dd)dW S  t jy@   td+| d, dd-d Y S  tyc } ztd.t|  dt|dW  Y d}~S d}~ww )/ah  
    Initiate a call to a senior using Vapi.ai (which handles Twilio internally)
    
    Args:
        senior_id: ID of the senior to call
        call_purpose: Purpose of the call
        user_id: ID of the user initiating the call
        prompt_id: ID of the CallPrompt to use (optional)
        assistant_id: ID of the VapiAssistant to use (required)
    )idr   )VapiAssistantz-assistant_id is required for initiating callserrorzassistant_id is requiredstatusmessageT)r   	is_activezAssistant with ID z not found or inactivezAssistant not found or inactiveNzPrompt with ID z, not found or inactive, using default prompt)
is_defaultr   zUsing default prompt: z+No default prompt set, using system default	initiated)seniorcall_purposeinitiated_by_idprompt	assistanttwilio_statuszCall initiated to z with assistant )purpose	prompt_idassistant_idcall
event_typer   dataprompt_generatedzAI prompt generated for )prompt_lengthr   zGenerated AI prompt for : z charactersstartedringingvapi_startedzVapi call started with ID: vapi_call_idz'Call initiated successfully for senior success)r   call_idr+   failedvapi_failedzFailed to start Vapi callzVapi call creation failedzSenior with ID 
 not foundzSenior not foundzError initiating call: )r   objectsgetcalls.modelsr   loggerr   DoesNotExistr	   warninginfonamer   creater   generate_ai_prompt	ai_promptsavelenstart_vapi_callr+   vapi_statusr   r   	Exceptionstr)self	senior_idr   user_idr   r    r   r   r   r   r"   r;   r+   e rF   $/var/www/html/philips/calls/tasks.pyinitiate_call_task   s   





rH   c                 C   sJ  t jj| ddddd }d}| r|d }g }|jr'|d|j  |jr6|d	d
|j  |j	rE|dd
|j	  |j
rT|dd
|j
  |jrg|dd
|jdd   d|}|d7 }|d7 }|d7 }|d7 }|d7 }|d7 }nd}ddlm} t }|j}	|j}
|j}|j}|j}dddddddddd d!d"d#}d$d%d&d'd(d)d*d+}||
d,|
 }|	 d-| d.| }|d/d0|d/}| }||d1}td2| d
| d
| d3|
 d4|	 d5| d6 | j| jrt| jnd7| jrd
| jnd8| jr| jnd9|||||t|jd:
}|rm|jrmz
|jjd]i |W S  tyO } zt d;| d< W Y d}~n"d}~w t!yl } zt"d=t| d< W Y d}~nd}~ww dg d>|d?  d@|dA  d
|dB  dC|dD  dE|dF  dG|dH  dI|dJ  dK|dL  dM|dN  dO|dP  dQ|d?  d@|dA  dR|dB  dS|dD  dT|d?  d@|dA  dU|dB  dV|dD  dW|dA  dX|dD  dY|dA  dZ|d?  d@|dA  d
|dB  d[|dA  d\}|S )^a  
    Generate an AI prompt for the call with memory context
    If a CallPrompt is provided, use its template; otherwise use the default prompt
    
    Args:
        senior: Senior instance
        call_purpose: Purpose of the call
        prompt: CallPrompt instance (optional)
    	completed)call__seniorcall__twilio_statusz-created_atN    r   u(   Zusammenfassung des letzten Gesprächs: zBesprochene Themen: , zBeobachtete Emotionen: zThemen zum Nachfragen: zFragen zum Stellen: z\num   \n\nWICHTIG: Verwenden Sie diesen Kontext aus vorherigen Gesprächen natürlich und einfühlsam. Sie können:uO   \n- Auf Themen eingehen, die sie zuvor erwähnt haben, wenn es natürlich passtu@   \n- Nachfragen zu Dingen stellen, über die sie gesprochen habenz?\n- Sich nach Sorgen oder Interessen erkundigen, die sie hattenuJ   \n- Ihr vorheriges Gespräch warm anerkennen, wenn sie sich daran erinnernu   \n\nDenken Sie daran: Erzwingen Sie keine Verbindungen - erwähnen Sie vorherige Gespräche nur, wenn es relevant und natürlich zum aktuellen Gespräch passt.u   Dies ist Ihr erstes Gespräch mit diesem Senioren. Konzentrieren Sie sich darauf, warm und einladend zu sein und etwas über ihre Interessen und Vorlieben zu erfahren.datetimeJanuarFebruar   MärzAprilMaiJuniJuliAugust	SeptemberOktoberNovemberDezember      rL                  	   
         MontagDienstagMittwoch
DonnerstagFreitagSamstagSonntagr   r^   r_   rL   r`   ra   rb   zMonth .  02d:	UnbekanntzCurrent date set for AI: z Uhr (Month: z, Day: z, Year: )zNicht angegebenu   Allgemeines GesprächKeine)
senior_name
senior_age	interestshealth_notesr   conversation_contextcurrent_datecurrent_timecurrent_weekdaycurrent_yearz6Error formatting prompt template: missing placeholder z. Using default prompt.z"Error formatting prompt template: u<   ⚠️ KRITISCH WICHTIG - AKTUELLES DATUM ⚠️
HEUTE IST: r   , der r}   r~   z Uhr.
Das aktuelle Jahr ist r   u  .
VERWENDEN SIE DIESES DATUM IMMER - NIEMALS OKTOBER ODER EIN ANDERES DATUM!

Sie sind ein freundlicher, geduldiger und einfühlsamer Gesprächspartner für Menschen mit früher oder fortgeschrittener Demenz. Sie müssen IMMER auf Deutsch sprechen. Sprechen Sie langsam, deutlich und verwenden Sie einfache, kurze Sätze. Wiederholen Sie wichtige Informationen sanft, wenn sie vergessen oder missverstanden wurden. Ihre Rolle ist es, ein Gefühl von Sicherheit, Orientierung und emotionaler Wärme zu vermitteln.

Sie können sich an einfachen Gesprächen über alltägliche Themen beteiligen (z.B. Familie, Essen, Wetter, Musik, Erinnerungen, Hobbys). Reagieren Sie immer positiv - niemals korrigierend oder belehrend. Wenn die Person verwirrt wirkt, führen Sie das Gespräch sanft zu vertrauten und angenehmen Themen. Wenn sie nach einem geliebten Menschen fragen, beruhigen Sie sie ruhig (z.B. "Ich denke, sie kommen bald zurück."). Vermeiden Sie medizinische oder negative Aussagen. Sprechen Sie in ruhigem, freundlichem Ton, wie ein vertrauenswürdiger Freund oder Betreuer. Lassen Sie Pausen im Gespräch, damit die Person Zeit hat zu antworten. Zeigen Sie Verständnis und Mitgefühl durch Ihre Worte ("Das kann ich wirklich verstehen", "Das klingt schön", "Das ist eine schöne Erinnerung").

Ziel: Das Gespräch sollte die Person emotional stabilisieren, trösten und sanft einbeziehen - wie ein guter Freund, der einfach da ist und zuhört.

Informationen zum Senioren:
- Name: rx   z

- Alter: ry   z
- Interessen: rz   z
- Gesundheitshinweise: r{   u   

Gesprächszweck: r   u  

Richtlinien für demenzfreundliche Kommunikation:
1. Sprechen Sie langsam und deutlich
2. Verwenden Sie einfache, kurze Sätze
3. Wiederholen Sie wichtige Informationen sanft, wenn sie vergessen wurden
4. Reagieren Sie immer positiv - niemals korrigieren oder belehren
5. Führen Sie verwirrte Gespräche zu vertrauten, angenehmen Themen
6. Beruhigen Sie ruhig über geliebte Menschen ("Ich denke, sie kommen bald zurück")
7. Vermeiden Sie medizinische oder negative Aussagen
8. Sprechen Sie wie ein vertrauenswürdiger Freund oder Betreuer
9. Lassen Sie Pausen für Antworten
10. Zeigen Sie Verständnis und Mitgefühl
11. Konzentrieren Sie sich auf emotionale Stabilität und Komfort
12. Seien Sie wie ein guter Freund, der einfach zuhört

Kontext aus vorherigen Gesprächen:
r|   u   

WICHTIG: Sie müssen während des gesamten Gesprächs auf Deutsch kommunizieren. Alle Ihre Antworten müssen auf Deutsch sein.

AKTUELLES DATUM UND ZEIT:
- Heute ist: z
- Aktuelle Uhrzeit: z Uhr
- Aktuelles Jahr: u   

KRITISCH WICHTIG - DATUM UND ZEIT:
Sie MÜSSEN das oben angegebene Datum verwenden. Es ist das EINZIGE korrekte Datum für heute.

- Das AKTUELLE Datum ist: z
- Die AKTUELLE Zeit ist: z Uhr
- Das AKTUELLE Jahr ist: zo

VERBOTEN - Verwenden Sie NIEMALS diese falschen Daten:
- NICHT Oktober (Oktober ist der 10. Monat, heute ist z - das ist NICHT Oktober!)
- NICHT Oktober 26 oder Oktober 2024 oder Oktober 2025
- NICHT April 2023
- NICHT 2023 als Jahr
- NICHT 2024 als Jahr (das aktuelle Jahr ist u^   )
- NICHT irgendein anderes Datum außer dem oben angegebenen

WICHTIG: Der aktuelle Monat in z ist der korrekte Monat. Oktober (Monat 10) ist FALSCH!

Wenn Sie nach dem Datum gefragt werden, antworten Sie EXAKT so:
"Heute ist z Uhr."

Das Datum ud   ist das EINZIGE korrekte Datum für heute. Verwenden Sie es IMMER.

Denken Sie daran: Dieses Gespräch wird zusammengefasst und gespeichert, um zukünftige Anrufe zu personalisieren. Konzentrieren Sie sich darauf, emotionalen Komfort, Sicherheit und sanfte Einbeziehung zu schaffen - bewahren Sie ihre Geschichten und bieten Sie emotionale Unterstützung.rF   )#r
   r1   filterorder_byexistssummaryappendtopics_discussedjoinemotions_detectedfollow_up_topicsfollow_up_questionsrP   r   nowdaymonthyearhourminuter2   weekdayr4   r7   r8   agerA   rz   r{   prompt_templateformatKeyErrorr6   r@   r   )r   r   r   recent_conversationsr|   last_conversationcontext_partsrP   r}   r   	month_numr   r   r   	months_deweekdays_demonth_name_dedate_strtime_strweekday_num
weekday_detemplate_varsrE   base_promptrF   rF   rG   r:      s    

0"
"''()../037:===?Cr:   c              
   C   s   | j r| j nd}| j|d}| jrLz| j}| D ]\}}|d| d|}q|W S  tyK } ztd| j dt| d W Y d}~nd}~ww d	|v rpd
|	 v s\d|	 v rfd| j d| dS d| j d| dS d| j d| dS )z
    Generate a personalized greeting that references previous conversations if available.
    Uses senior's custom first_message if set, otherwise generates default greeting.
    Supports template variables: {senior.name} and {companion.name}
    zIhr KI-Begleiter)zsenior.namezcompanion.name{}z*Error formatting custom first_message for r'   z. Using default greeting.Nu'   Zusammenfassung des letzten Gesprächs:
gesundheitu   gefühlzHallo uf   ! Ich rufe an, um nachzufragen, wie es Ihnen heute geht. Ich hoffe, alles geht gut für Sie. Hier ist .ub   ! Es ist schön, wieder mit Ihnen zu sprechen. Ich wollte nachfragen, wie es Ihnen geht. Hier ist z! Hier ist uO   . Ich rufe an, um nachzufragen und ein schönes Gespräch mit Ihnen zu führen.)
companion_namer8   first_messageitemsreplacer@   r4   r6   rA   lower)r   r;   r   r   greetingkeyvaluerE   rF   rF   rG   generate_personalized_greetingB  s&   *r   c                 C   s  zPdt j dd}ddd}|rY| rYz&tjd| |d}|jd	kr;| }|d
|}td| d|  W n t	yX } zt
dt|  W Y d}~nd}~ww t|dkre|dd n|}ddl}	|	d|}
|
rx|
dnd}td| j d|  td|  ddlm} t }|j}|j}|j}ddddddddd d!d"d#d$}d%d&d'd(d)d*d+d,}||d-}|| d-}| d.| d/| }d0| d1| d2| d3| d4| d5| d6| d7| d8| d9| d:| d;|  }d<| j d=d>d?|d@gdAdB|t| |dC}tdD| j dE|  tjdF||dG}|jdHkrB| }tdI| j d|dJ   |dJ W S tdK|j dL|j  W dS  t	yo } ztdMt|  W Y d}~dS d}~ww )Na8  
    Create a Vapi.ai assistant with custom system prompt for this senior
    Uses the configured voice settings from the provided base_assistant_id
    
    Args:
        senior: Senior instance
        ai_prompt: AI prompt text
        base_assistant_id: Base VAPI assistant ID to copy voice settings from
    Bearer application/jsonAuthorizationzContent-Typeazurezde-DE-KatjaNeural)providervoiceIdzhttps://api.vapi.ai/assistant/headers   voicez'Using voice config from base assistant r'   z-Could not fetch base assistant voice config: N  r   zder (\d+\. \w+ \d{4})r^   z	NOT FOUNDzCreating Vapi assistant for z - Date in prompt: z"Prompt preview (first 500 chars): rO   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   ri   rj   rk   rl   rm   rn   ro   rp   ru   rq   rr   z.SYSTEM INFORMATION - MANDATORY:
CURRENT DATE: z
CURRENT YEAR: z
CURRENT MONTH: z (Month z)
CURRENT DAY: z
CURRENT WEEKDAY: z!

YOU MUST ALWAYS USE THIS DATE: z9
NEVER SAY OCTOBER - OCTOBER IS MONTH 10, TODAY IS MONTH z (z1)
IF ASKED FOR DATE, RESPOND EXACTLY: "Heute ist r   z"

zSenior Companion - openaizgpt-4o-minisystem)rolecontentffffff?)r   modelmessagestemperature)r8   r   r   firstMessagez)Creating personalized Vapi assistant for z with voice: zhttps://api.vapi.ai/assistantr   json   z5Personalized Vapi assistant created successfully for r   z!Failed to create Vapi assistant: z - zError creating Vapi assistant: )r   VAPI_API_KEYstriprequestsr2   status_coder   r4   r7   r@   r6   rA   r=   researchgroupr8   rP   r   r   r   r   r   r   r   postr   text)r   r;   base_assistant_idr   voice_configresponseexisting_assistantrE   prompt_date_checkr   
date_matchdate_in_promptrP   r}   r   r   r   r   r   r   r   current_date_strenhanced_promptassistant_configr   rF   rF   rG   !create_vapi_assistant_with_promptf  s   


 		

r   c           	   
   C   st  zdt j dd}| jstd| j  W dS | jj}td| jj d| d|j  td	|j d
 t	|| j
|}|sMtd|j  W dS || _|   |t jd|jid}td|j d|  tjd||d}|jdv r| }td|  td|  |dW S td|j  W dS  ty } ztdt|  W Y d}~dS d}~ww )zU
    Start a Vapi.ai call with the generated prompt using the selected assistant
    r   r   r   zNo assistant assigned to call NzUsing base assistant z (ID: z) for z$Creating personalized assistant for z with custom promptz,Failed to create personalized assistant for number)assistantIdphoneNumberIdcustomerzStarting Vapi call for z with assistant: zhttps://api.vapi.ai/callr   )r   r   z Vapi call created successfully: zUsing assistant: r   zVapi call failed: zError starting Vapi call: )r   r   r   r4   r   r   r    r7   r8   r   r;   vapi_assistant_idr<   VAPI_PHONE_NUMBER_IDphone_numberr   r   r   r   r2   r   r@   rA   )	r"   r   r   r   r    r$   r   resultrE   rF   rF   rG   r>     sN   
"
r>   c                 C   s  zdt j dd}tjjg dd}tjjddd}d	}|D ]}z|jsgd	d
lm} |jdkre|j	t
 |dd k retd|j d d|_d|_|  |d7 }tjj|ddddddd W q tjd|j |d}|jdkr| }|dd}	t|	 }
|
dd }
|
dkrd}
dd dddd!d"dd#dddd$}|
|v r||
 }|j}d}|dkr|jst
 |_d%}||krtd&|j d'| d(|  ||_|
|_|dkr|jst
 |_|d)p|d*p|d+}t|ttfr|r|d,krt|d, }|r||_|dkr6|dkr6t
 |_ |jr6|js6|j |j ! }t||_|dkrt"jj|d-# swtd.|j  zt$|| W n* t%yv } zt&d/|j d0t|  W Y d1}~nd1}~ww t'd2|j  |  |d7 }tjj|dd3| d(| d4|||
|d5d n1|r|  |d7 }tjj|dd6d|id nt'd7|j d8|  nt(d9|j d0|
  W q  t%y } zt&d:|j d0t|  W Y d1}~q d1}~ww d	}|D ]}zt"jj|d-# s{td;|j d< tjd|j |d}|jdkrn| }|dd}
|
d=v rmtd>|j  zt$|| |d7 }td?|j  W n/ t%yl } zt&d/|j d0t|  W Y d1}~nd1}~ww nt(d@|j d0|j  W q t%y } zt&dA|j d0t|  W Y d1}~qd1}~ww tdB| dC| dD dE||dFW S  t%y } zt&dGt|  dHt|dIW  Y d1}~S d1}~ww )JzA
    Check Vapi.ai for call statuses and update our database
    r   r   r   )r   r)   in-progress)twilio_status__inrI   F)r   vapi_call_id__isnullr   )	timedeltar   ra   )minuteszMarking call z, as failed (no Vapi Call ID after 5 minutes)r.   r^   status_changedz8Status updated to failed (no Vapi Call ID after timeout)timeout)
old_status
new_statusreasonr!   zhttps://api.vapi.ai/call/r   r   r   unknown_-
inprogressr   r)   busy	no_answer	cancelledqueuedr)   r   rI   endedr   z	no-answerr.   canceledansweredr(   	connectedTzUpdating call  status from  to durationdurationSecondsduration_ms  r"   z0Processing conversation data for completed call z'Error processing conversation for call r'   N%Conversation already exists for call Status updated from z via Vapi API check)r   r   r?   r   z0Start time set while status remained in-progresszCall  status unchanged: zUnknown Vapi status for call zError checking call zChecking completed call z for conversation processing)rI   r   z+Processing conversation for completed call z-Successfully processed conversation for call z#Could not fetch VAPI data for call z Error processing completed call zUpdated z call statuses and processed z conversationsr,   )r   updated_countconversations_processedz)Error in check_and_update_call_statuses: r   r   ))r   r   r   r1   r   r+   rP   r   r   
created_atr   r   r4   r7   r   r?   r<   r   r9   r   r2   r   r   rA   r   r   r   call_start_time
isinstanceintfloatr   call_end_timetotal_secondsr
   r   process_completed_call_from_apir@   r   debugr6   )rB   r   active_callscompleted_callsr  r"   r   r   	call_datavapi_status_rawr?   status_mappingr   r   start_time_setr   duration_secondsrE   conversation_processed_countrF   rF   rG   check_and_update_call_statuses  s$  

"





 


((


(	*r  c                 C   s  z^| d}| d}|durt| nd}|dd }|dkr&d}|s3td	 d
ddW S z	tjj |d}W n tj	yU   td| d d
dd Y W S w ||_
ddddddddddddd}||v r)|j}|| }d}	|dkr|jst |_d}	||krtd|j d| d|  ||_|dkr|jst |_|dkr|dkrt |_| dp| dp| d }
t|
ttfr|
r|
d!krt|
d! }
|
r|
|_|jr|js|j|j  }t||_|  tjj|d"d#| d| d$|||d%d& n-|	r|  tjj|d"d'd|id& ntd(|j d)|  ntd*|j d+|  |  |d,v rCt|| tjj|d-d.| |d& td/|j  d0|jd1W S  ty } ztd2t|  d
t|dW  Y d}~S d}~ww )3z
    Process Vapi.ai webhook data and update conversation records
    
    Args:
        webhook_data: Data received from Vapi webhook
    callIdr   Nr   r   r   r   r   zNo callId in Vapi webhook datar   zNo callId providedr   )r+   zCall with Vapi ID r0   zCall not foundr   r)   rI   r   r   r.   r   r   FTzWebhook: Updating call r   r   r   r   r   r  r   r  z via webhook)r   r   r?   r!   z:Start time set while status remained in-progress (webhook)zWebhook: Call r  z&Webhook: Unknown Vapi status for call r'   )r   rI   webhook_receivedzVapi webhook received: z Vapi webhook processed for call r,   )r   r-   zError processing Vapi webhook: )r2   rA   r   r   r   r4   r   r   r1   r5   r?   r   r	  r   r   r7   r   r  r
  r  r  r   r  r<   r   r9   r  r6   process_completed_callr@   )rB   webhook_datar-   
status_rawr   r"   r  r   r   r  webhook_durationr  rE   rF   rF   rG   process_vapi_webhook_task  s   












r   c                 C   s   zD| dd}| dd}tjj| ||t|t|t|t|t|t	|t
|d
}t| j|| t| j| td| jj  W dS  tya } ztdt|  W Y d}~dS d}~ww )zM
    Process a completed call and extract conversation data from webhook
    
transcriptrM   r   
r"   r!  r   r   key_memoriesr   sentiment_scoreengagement_levelr   r   z$Completed call processed for senior z!Error processing completed call: N)r2   r
   r1   r9   extract_topicsextract_memoriesextract_emotionsanalyze_sentimentassess_engagementgenerate_follow_up_topicsgenerate_follow_up_questionsextract_and_store_memoriesr   generate_insightsr4   r7   r8   r@   r   rA   )r"   r  r!  r   conversationrE   rF   rF   rG   r  \  s,   "r  c                 C   s  zlt jj| d rtd| j d W dS |dd}|dd}|s5|r5d| jj	 d	| j
p1d
 d}t jj| ||t|t|t|t|t|t|t|d
}t| j|| t| j| td| jj	  W dS  ty } ztdt|  W Y d}~dS d}~ww )zR
    Process a completed call and extract conversation data from API response
    r  r  z
, skippingNr!  rM   r   Conversation with z	 lasting r   z	 seconds.r"  z-Completed call processed from API for senior z*Error processing completed call from API: )r
   r1   r   r   r4   r7   r   r2   r   r8   r   r9   r&  r'  r(  r)  r*  r+  r,  r-  r.  r@   r   rA   )r"   api_datatranscript_textr   r/  rE   rF   rF   rG   r    s6   "r  c                    s   g }g dg dg dg dg dg dg dg dg d	g d
d
}|    | D ]\}}t fdd|D r?|| q+|S )z(Extract topics from conversation summary)	familychildrenkidssondaughtergrandchildrenspousehusbandwife)workjobcareerofficebusiness
retirement)	hobbyhobbiespaintingcodingfootballsportsmusicreading	gardening)travelvacationtripjourneyvisit)healthdoctormedicineexercisewalkingfeeling)foodcookingmeal
restaurantrecipe)weatherrainsunnycoldhot)rememberused to	back then	old times	childhood)dailyroutinemorningeveningschedule)friends	neighbors	communitysocialrO  )
r3  r<  rB  rK  rP  rV  r[  memoriesdaily_routinerm  c                 3       | ]}| v V  qd S NrF   .0keywordsummary_lowerrF   rG   	<genexpr>      z!extract_topics.<locals>.<genexpr>r   r   anyr   )r   topicstopic_keywordstopickeywordsrF   ru  rG   r&    s$   
r&  c                    s   g }g d}|    t fdd|D r|d d v r.t fdddD r.|d d	 v rBt fd
ddD rB|d |S )z.Extract key memories from conversation summary)remember whenra  rb  rc  rd  zwhen I was youngz	in my dayz	years agozstory aboutztold me aboutzshared a memoryzreminisced aboutc                 3   rp  rq  rF   )rs  	indicatorru  rF   rG   rw    rx  z#extract_memories.<locals>.<genexpr>zPersonal memories sharedr3  c                 3   rp  rq  rF   rs  wordru  rF   rG   rw    rx  )r`  ra  storyzFamily memoriesr<  c                 3   rp  rq  rF   r  ru  rF   rG   rw    rx  )r`  ra  r>  zWork/career memories)r   rz  r   )r   rn  memory_indicatorsrF   ru  rG   r'    s   


r'  c                    s`   g }g dg dg dg dd}|    | D ]\}}t fdd|D r-|| q|S )z*Extract emotions from conversation summary)happyjoysmilelaughexcited)sadmisslonely	depressed)r`  ra  rb  rc  )thankfulgratefulblessed
appreciate)r  r  	nostalgicr  c                 3   rp  rq  rF   rr  ru  rF   rG   rw    rx  z#extract_emotions.<locals>.<genexpr>ry  )r   emotionsemotion_keywordsemotionr~  rF   ru  rG   r(    s   
r(  c                    s`   g d}g d}|    t fdd|D }t fdd|D }||kr(dS ||kr.dS dS )	z%Analyze sentiment of the conversation)r  good	wonderfulgreatloveenjoy)r  badterriblehateworried	concernedc                 3       | ]	}| v rd V  qdS r^   NrF   r  ru  rF   rG   rw        z$analyze_sentiment.<locals>.<genexpr>c                 3   r  r  rF   r  ru  rF   rG   rw    r        ?g      g        )r   sum)r   positive_wordsnegative_wordspositive_countnegative_countrF   ru  rG   r)    s   r)  c                 C   s0   t | dkrd|  v rdS t | dkrdS dS )z5Assess engagement level based on conversation summaryr   r  highd   mediumlow)r=   r   )r   rF   rF   rG   r*    s
   r*  c                 C   sJ   g }d|   v r|d d|   v r|d d|   v r#|d |S )z*Generate follow-up topics for future callsr3  zfamily updatesrP  zhealth check-inrB  zhobby activitiesr   r   )r   r{  rF   rF   rG   r+  
  s   


r+  c                 C   s4   g }d|   v r|d d|   v r|d |S )z-Generate follow-up questions for future callsgardenzHow is your garden doing?r3  z"How are your family members doing?r  )r   	questionsrF   rF   rG   r,    s   

r,  c              
      sT  zd}d}d}|   t fdddD rd}d}d	}nGt fd
ddD r/d}d}d}n5t fdddD rAd}d}d	}n#t fdddD rSd}d}d}nt fdddD rdd}d}d}tjj| ||||dd ||dgd td| d | j d!|  W dS  ty } zt	d"| j d!t
|  W Y d}~dS d}~ww )#z:Extract and store important memories from the conversationfactzConversation Summaryr  c                 3   rp  rq  rF   rr  ru  rF   rG   rw  .  rx  z-extract_and_store_memories.<locals>.<genexpr>)r  ra  z
when i wasrb  r  zPersonal Story Shared皙?c                 3   rp  rq  rF   rr  ru  rF   rG   rw  2  rx  )liker  r  favoriteprefer
preferencezPersonal Preferencer   c                 3   rp  rq  rF   rr  ru  rF   rG   rw  6  rx  )r3  r6  r7  r:  r;  friendrelationshipzFamily/Friend Mentionc                 3   rp  rq  rF   rr  ru  rF   rG   rw  :  rx  )rP  rQ  rR  painrU  zHealth Update?c                 3   rp  rq  rF   rr  ru  rF   rG   rw  >  rx  )r<  r=  r>  achievementaccomplishedr  zWork/Career MentionNr   r/  )r   r/  memory_typetitler   importance_scoretagszCreated z memory for r'   zError creating memory for )r   rz  r   r1   r9   r4   r7   r8   r@   r   rA   )r   r/  r   r  r  r  rE   rF   ru  rG   r-     sN   
$
*r-  c              
      sR  z|j   d}|jdurO|jdkr/tjj| ddd|jdd|j|jd	d
d |d7 }n |jdk rOtjj| ddd|jdd|j|jd	dd |d7 }t fdddD rotjj| ddd|j|jddd |d7 }t fdddD rtjj| ddd|j|jdd
d |d7 }|j	rtjj| d|j	
  dd |j	 d!|j	|jd"d#d |d7 }|jrt|jdkrtjj| d$d%d&d'|j |j|jdd#d |d7 }|dkrtjj| dd(d)| j d*|jt|j d+d,d |d7 }td-| d.| j  W dS  ty( } ztd/| j d0t|  W Y d}~dS d}~ww )1z'Generate insights from the conversationr   Ng333333?
mood_trendzPositive Mood Detectedz)Senior showed positive sentiment (score: z.2fz) in recent conversation)r$  conversation_idr   )r   insight_typer  descriptionr$   confidence_scorer^   g333333ӿzConcern About Moodz)Senior showed negative sentiment (score: r  c                 3   rp  rq  rF   rr  ru  rF   rG   rw  w  rx  z$generate_insights.<locals>.<genexpr>)rP  rQ  rR  r  sickznot feeling wellillnesshealth_concernzHealth Discussionz;Health-related topics were discussed in recent conversation)r{  r  r  c                 3   rp  rq  rF   rr  ru  rF   rG   rw    rx  )r3  r6  r7  r:  r;  r  rO  r"   social_patternzSocial Connections DiscussedzBFamily or social connections were mentioned in recent conversationcommunication_stylez Engagement LevelzSenior showed z& engagement during recent conversation)r%  r  g333333?interest_changezTopics of Interestz Recent conversation focused on: rN   zConversation Recordedr0  z was recorded and analyzed)r  summary_lengthr  z
Generated z insights for zError generating insights for r'   )r   r   r$  r   r1   r9   r   rz  r   r%  r  r=   r   r8   r4   r7   r@   r   rA   )r   r/  insights_createdrE   rF   ru  rG   r.  T  s   




*r.  )r   NNNrq  )*celeryr   django.confr   django.utilsr   twilio.restr   r   r   loggingseniors.modelsr   r3   r   r   r	   conversations.modelsr
   r   r   	getLogger__name__r4   rH   r:   r   r   r>   r  r   r  r  r&  r'  r(  r)  r*  r+  r,  r-  r.  rF   rF   rF   rG   <module>   sD    

| 6
$v>
 B
#,
4