
    u1iM(                         d Z ddlZddlZddlmZ ddlmZmZmZ ddlm	Z	m
Z
mZmZ  ej                  dd      Zde	d	efd
Zde	d	eeef   fdZde	d	efdZde	d	ee   fdZde	d	e	fdZy)zN
Performance and Reporting Node
Generates campaign reports and tracks metrics
    N)datetime)AnyDictList)SEOCampaignStateCampaignPhasetransition_phase	add_errorNEXT_API_URLzhttp://127.0.0.1:3000statereturnc                 p  K   	 t        j                  d      4 d{   }|j                  t         dddt	        j
                  dd       i| d	   | d
   | d   | d   | | d   t        j                  j                  k(  rdnd| j                  dd      | j                  dd      | j                  dd      | j                  dd      d
       d{   }|j                  dv cddd      d{    S 7 7 %7 	# 1 d{  7  sw Y   yxY w# t        $ r}t        d|        Y d}~yd}~ww xY ww)z'Save campaign state to database via APIg      >@)timeoutNz/api/admin/seo/campaigns/saveAuthorizationzBearer INTERNAL_API_TOKEN campaign_idsite_idcampaign_typecurrent_phase	completedactivepages_generatedr   snippets_capturedlinks_approvedlinks_acquired)

campaignIdsiteIdcampaignTypecurrentPhasestateSnapshotstatuspagesGeneratedsnippetsCapturedlinksApprovedlinksAcquired)headersjson)      z[PerformanceNode] Save error: F)httpxAsyncClientpostr   osgetenvr   	COMPLETEDvaluegetstatus_code	Exceptionprint)r   clientresponsees       9/var/www/html/langgraph-service/nodes/performance_node.pysave_campaign_to_dbr:      sN    4$$T2 	6 	6f#[[. =>(GBII>RTV4W3X*YZ"'"6#I.$)/$:$)/$:%*-2?-C}G^G^GdGd-dkjr&+ii0A1&E(-		2Eq(I%*YY/?%C%*YY/?%C )  H  '':5#	6 	6 	6	6 	6 	6 	6(   4.qc2334s   D6D C7D B1C=C9C=%D 1C;2D 6D67D 9C=;D =DDDD D6D 	D3D.)D6.D33D6c                 2   | j                  dg       }t        |D cg c]  }|j                  d      dk(  s| c}      }t        |D cg c]  }|j                  d      dk(  s| c}      }t        |D cg c]  }|j                  d      dk(  s| c}      }| j                  dg       }t        |D cg c]  }|j                  d      dk(  s| c}      }t        |D cg c]  }|j                  d      d	k(  s| c}      }	| j                  d
g       }
t        |
D cg c]  }|j                  d      dk(  s| c}      }t        |
D cg c]  }|j                  d      d	k(  s| c}      }| j                  dg       }t        |D cg c]  }|j                  d      dk(  s| c}      }t        |D cg c]  }|j                  d      dk(  s| c}      }t        |D cg c]  }|j                  d      dk(  s| c}      }t        |D cg c]  }|j                  d      s| c}      }| j                  d      }d}|r^|j                  dd      |j                  dd      t        |j                  dd      dz  d      t        |j                  dd      d      d}g }| j                  dg       D ]N  }|j                  |j                  d      |j                  d      t        |j                  dg             d       P | d    | d!   | d"   | j                  d#g       t	        |       |||t        |      d$||	| j                  d%d      d&||| j                  d'd      d(t        |      ||||d)||t        | j                  d*g             t        | j                  d+g             t        j                         j                         d,S c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w )-z+Generate a metrics summary for the campaignserp_features_datafeature_typesnippetpaaai_overviewcontent_queuer"   queuedr   optimization_queuelink_opportunitiesapprovedrejectedpendinglink_acquiredgsc_dataNtotal_impressionsr   total_clicksaverage_ctrd      average_position   )rJ   rK   rL   rO   competitor_datadomaindomain_authoritycontent_gaps)rR   rS   content_gaps_foundr   r   r   phases_completed)snippet_opportunitiespaa_opportunitiesai_overview_opportunitiestotal_opportunitiesr   )pages_queuedpages_completedr   pages_optimized)optimizations_queuedoptimizations_completedr]   )opportunities_foundpending_approvalrE   rF   acquirederrorswarnings)r   r   r   rV   duration_secondsserp_featurescontentoptimizationlinksgsccompetitors_analyzedrc   rd   generated_at)r2   lenroundappendcalculate_durationr   utcnow	isoformat)r   rf   fsnippet_oppspaa_oppsai_overview_oppsrA   ccontent_queuedcontent_completed	opt_queueo
opt_queuedopt_completed	link_oppslr   links_rejectedlinks_pendingr   rI   gsc_summarycompetitor_summarycomps                           r9   generate_metrics_summaryr   0   s    II2B7M=WaAEE.4IY4VWXL}O!n0E0NAOPH}_!n8MQ^8^A_` IIor2M]RaeeHo6Q!RSNX1xK9WQXY 		.3IJAaeeHo.IaJKJIPqxK1OPQM 		.3IYP!%%/Z2O!PQNYP!%%/Z2O!PQNINqxI1MNOMYI!%%2H!IJN yy$HK!).A1!E$LL; mQ!?#!EqI %hll3Eq&I1 M	
 		+R0 !!hhx( $); <"%dhh~r&B"C#
 	 ]+#/!II&8"=.u5 &2!))9#&}#5	
 +0$yy):A>
 %/'4$yy):A>
 $'y> -&&&
  2eii"-.		*b12 )335Q) )S XO_ SX KP QPNIs   O"O"
O'$O'8O,O,8O1O1&O6 O6&O; O;P .P P.PP
P
0P
PP5Pc                     	 t        j                  | j                  dd            }t        j                  | j                  dd            }t        ||z
  j	                               S # t
        $ r Y yw xY w)z&Calculate campaign duration in seconds
started_atr   
updated_atr   )r   fromisoformatr2   inttotal_secondsr4   )r   startedendeds      r9   rp   rp      sg    ((<)DE&&uyyr'BCEGO22455 s   A%A( (	A43A4c                    g }| j                  dg       }|D cg c]+  }|j                  d      dk(  s|j                  d      r*|- }}|r|j                  dt        |       d       |D cg c]  }|j                  d      dk(  s| }}|r|j                  dt        |       d	       | j                  d
g       }|D cg c]  }|j                  dd      dk\  s| }}|r|j                  dt        |       d       | j                  dg       }	|	D 
cg c]  }
|
j                  d      dk(  s|
 }}
|r|j                  dt        |       d       | j                  d      }|rL|j                  dd      dk  r|j                  d       |j                  dd      dkD  r|j                  d       |s|j                  d       |S c c}w c c}w c c}w c c}
w )z=Generate actionable recommendations based on campaign resultsr<   r=   r>   capturedz	Optimize zd pages for featured snippets - focus on 'What is' and 'How to' query formats with 40-60 word answersr@   zTarget z^ AI Overview opportunities - ensure content has unique data points and clear authority signalsrA   priorityr      zPrioritize zJ high-priority content pieces - these have the best SERP feature potentialrD   r"   rG   zReview zV pending link opportunities - all opportunities require human approval before outreachrI   rL   gQ?zdCTR is below 3% - consider optimizing title tags and meta descriptions for click-through improvementrO   rM      zfAverage position is outside top 15 - focus on content quality and internal linking to improve rankingszfContinue monitoring SERP features and competitor movements - run this campaign weekly for best results)r2   ro   rm   )r   recommendationsrf   rs   uncaptured_snippetsrv   rA   rw   high_priorityr~   r   rG   rI   s                r9   generate_recommendationsr      s!   O II2B7M&3tquu^7LPY7Ybcbgbghrbs1tt/01 2T U	

 $1[aAEE.4I]4Z[[c*+, -P Q	
 IIor2M -K1z11E1JQKMK#m,- .9 :	
 		.3I#DQquuX)'CqDGDc'l^ $G H	
 yy$H<<q)D0""0 <<*C025""; 8	

 k u \ L Es4   GGG/G	GG GG6Gc           	        K   t        d| d           t        j                         j                         }	 t	        |       }t        d|d   d    d|d   d    d	       t        |       }t        d
t        |       d       | j                  di       | d<   ||| j                  dg       | j                  dg       d| d   d<   	 t        |        d{   }|st        d       t        | t        j                        } || d<   || d<   t        d       | S 7 B# t        $ r}t        d|        Y d}~Od}~ww xY w# t        $ r}t        d|        t        | ddt        |             } | j                  di       | d<   dt        |      idg| j                  dg       | j                  dg       d| d   d<   Y d}~d}~ww xY ww)z
    Report generation phase node

    - Generates comprehensive campaign metrics
    - Creates actionable recommendations
    - Saves final state to database
    - Marks campaign as completed
    z1[PerformanceNode] Generating report for campaign r   z[PerformanceNode] Metrics: rg   r   z pages, ri   r`   z link opportunitiesz[PerformanceNode] Generated z recommendationsconfigrc   rd   )metricsr   rc   rd   final_reportNzB[PerformanceNode] Warning: Could not save campaign to database APIz3[PerformanceNode] Database save error (non-fatal): z+[PerformanceNode] Error generating report: reportzReport generation error: errorz$Check system configuration and retrycompleted_atr   z$[PerformanceNode] Campaign completed)r5   r   rq   rr   r   r   rm   r2   r:   r4   r
   strr	   r   r0   )r   nowr   r   savedr8   s         r9   generate_report_phaser      s     
=eM>R=S
TU
//

%
%
'C%
*51+GI,>?P,Q+RRZ!"7899LN 	O 359,S-A,BBRST  ))Hb1h.ii"-		*b1	+
h'	M-e44EZ[" UM$;$;<EE.E,	02L3 5  	MGsKLL	M  

;A3?@%-Fs1vh+OP))Hb1hQ( FGii"-		*b1	+
h'

sf   4GBD= D DD &1GD 	D:"D50D= 5D::D= =	GA5G ;G GG)__doc__r.   r+   r   typingr   r   r   state.campaign_stater   r   r	   r
   r/   r   boolr:   r   r   r   rp   r   r        r9   <module>r      s   
 
   " "  ryy)@A%5 $ 4W$4 Wc3h Wt. 3 ;$4 ;c ;|;'7 ;<L ;r   