
    P1iU                         d dl mZ d dl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Zdd	lmZ d
 Zde_        d Zde_         ej$                  e       G d dej&                               Zy)    )admin)format_html)	mark_safe)pathreverse)HttpResponseRedirect)messagesN   )Personc                     |D ]  }	 ddl m}  ||        | j                  |d|j                          d       y# t        $ r5}| j                  |d|j                   dt        |              Y d}~rd}~ww xY w)z8Admin action to generate AI analysis for selected peopler   )analyze_bazizError generating analysis for : NzAnalysis requested for z people)ai.utils.bazir   	Exceptionmessage_usernamestrcount)
modeladminrequestquerysetpersonr   es         ,/home/cursorai/projects/iching/bazi/admin.pygenerate_ai_analysisr   
   s    	g2 	  G'>x~~?O>PPW%XY  	g##G/Mfkk]Z\]`ab]c\d-eff	gs   <	A:+A55A:zGenerate AI analysisc                     d}|D ]0  }d|_         d|_        d|_        |j                  g d       |dz  }2 | j	                  |d| d       y)z5Admin action to reset AI analysis for selected peopler   Nai_analysisanalysis_timestampanalysis_statusupdate_fieldsr
   zAI analysis reset for z/ people. You can now regenerate their analysis.)r   r   r    saver   )r   r   r   updated_countr   s        r   reset_ai_analysisr%      s_    M!$(!!%"Z[  G'=m_L{%|}    z'Reset AI analysis (allows regeneration)c            	       t    e Zd ZdZdZdZdZeeddgZ	ddd	ifd
ddifdddifdddifddddfddddfdddiffZ
 fdZ fdZd Zd Zd Zde_        d Zde_        d  Zd!e_        d"e_        d# Zd$e_        d% Zde_        d& Zde_        d' Zd(e_        d) Zd*e_        d+ Zd,e_        d- Zd.e_         xZS )/PersonAdmin)r   
birth_date
birth_timecreated_by_display
created_atanalysis_status_displaybazi_report_status_displaynumber_report_status_display)r,   
created_byr    bazi_report_statusnumber_report_statusbazi_analysis_reportednumber_analysis_reported)r   notescreated_by__first_namecreated_by__last_namecreated_by__phonebazi_report_messagenumber_report_message)r,   
updated_atr0   r   r    ai_analysis_displayreset_ai_analysis_buttonnumber_ai_analysis_displayreset_number_ai_analysis_buttonbazi_report_timestampbazi_report_resolved_bybazi_report_resolved_atnumber_report_timestampnumber_report_resolved_bynumber_report_resolved_atresolve_bazi_reportsresolve_number_reportszBasic Informationfields)r   genderr)   r*   	twin_type
father_dob
mother_dobr5   z
Chart Data)bazi_resultnumber_resultzBaZi AI Analysis)r    r   r<   r=   zNumber AI Analysis)number_analysis_statusnumber_analysis_timestampr>   r?   zBaZi Analysis Reports)r3   bazi_report_categoryr9   r@   r1   bazi_report_admin_notesrB   )collapse)rH   classeszNumber Analysis Reports)r4   number_report_categoryr:   rC   r2   number_report_admin_notesrE   System)r,   r;   r0   c                    ddl m} |rcd|j                  v rU|j                  j	                  dd      }|j
                  j	                  dd      }|r|sd|_        | j                  |d       |rcd|j                  v rU|j                  j	                  dd      }|j
                  j	                  dd      }|r|sd|_        | j                  |d       |rd|j                  v r|j                  j	                  dd	      }|j
                  j	                  dd	      }	|	d
v r&|j                  |_
        |j                         |_        |	dk(  r|j                  sy	 ddlm}
 |j                  rf|j                  j                   rP |
|j                  |d|	|j"                         d|_        | j                  |d|j                  j                           |rd|j                  v r|j                  j	                  dd	      }|j
                  j	                  dd	      }	|	d
v r&|j                  |_        |j                         |_        |	dk(  r|j                  sy	 ddlm}
 |j                  rf|j                  j                   rP |
|j                  |d|	|j,                         d|_        | j                  |d|j                  j                           t.        | a  ||||       y# t$        $ r)}| j                  |dt'        |              Y d}~<d}~ww xY w# t$        $ r(}| j                  |dt'        |              Y d}~td}~ww xY w)zJOverride save_model to send email notifications when report status changesr   timezoner3   Fz5BaZi report reset - email flag cleared for new reportr4   z7Number report reset - email flag cleared for new reportr1    )resolved	dismissedr\   !send_user_resolution_notificationbaziTzEmail notification sent to z(Report status updated but email failed: Nr2   number)django.utilsrZ   changed_datainitialgetcleaned_data!bazi_report_resolution_email_sentr   #number_report_resolution_email_sentuserrA   nowrB   	api.utilsr_   r0   emailrR   r   r   rD   rE   rV   super
save_model)selfr   objformchangerZ   old_reportednew_reported
old_status
new_statusr_   r   	__class__s               r   rn   zPersonAdmin.save_modelE   s   ) .$2C2CC<<++,DeLL,,001I5QL L8=5!!'+bc 0D4E4EE<<++,FNL,,001KUSL L:?7!!'+de *d.?.??))*>CJ**../CRHJ 66.5ll+.6lln+ Z'0U0U	dK~~#..*>*>9NNCSE`E` AE=))'5PQTQ_Q_QeQePf3gh
 ,0A0AA))*@"EJ**../ErJJ 6607-08- Z'0W0W	dK~~#..*>*>9NNC:sGdGd CG?))'5PQTQ_Q_QeQePf3gh
 	7Cv69 ! d%%g1YZ]^_Z`Ya/bccd0 ! d%%g1YZ]^_Z`Ya/bccds2   A8K A8L 	L&L

L	ML>>Mc                     t         |          }t        d| j                  j	                  | j
                        d      t        d| j                  j	                  | j                        d      g}||z   S )z,Add custom URLs for the reset functionality.z"<int:person_id>/reset-ai-analysis/bazi_person_reset_ai_analysis)r   z)<int:person_id>/reset-number-ai-analysis/$bazi_person_reset_number_ai_analysis)rm   get_urlsr   
admin_site
admin_viewreset_ai_analysis_viewreset_number_ai_analysis_view)ro   urlscustom_urlsrw   s      r   r{   zPersonAdmin.get_urls   sr    w!4**4+F+FG4
 ;**4+M+MN;
 T!!r&   c                    	 t         j                  j                  |      }d|_        d|_	        d|_
        |j                  g d       t	        j                  |d|j                   d	       t        t        d
|g            S # t         j                  $ r1 t	        j
                  |d| d       t        t        d            cY S w xY w)zCCustom view to handle BaZi AI analysis reset for individual person.idPerson with ID  does not exist.admin:bazi_person_changelistNr   r!   zBaZi AI analysis reset for z-. You can now regenerate their BaZi analysis.admin:bazi_person_changeargs)r   objectsre   DoesNotExistr	   errorr   r   r   r   r    r#   successr   ro   r   	person_idr   s       r   r~   z"PersonAdmin.reset_ai_analysis_view   s    	Q^^''9'5F "$(!!%"Z[$?}Ly"z{ $G,Fi[$YZZ "" 	QNN7oi[@P$QR'0N(OPP	Q    B AC
	C
c                    	 t         j                  j                  |      }d|_        d|_	        d|_
        |j                  g d       t	        j                  |d|j                   d	       t        t        d
|g            S # t         j                  $ r1 t	        j
                  |d| d       t        t        d            cY S w xY w)zECustom view to handle Number AI analysis reset for individual person.r   r   r   r   N)number_ai_analysisrP   rO   r!   zNumber AI analysis reset for z/. You can now regenerate their Number analysis.r   r   )r   r   re   r   r	   r   r   r   r   rP   rO   r#   r   r   r   s       r   r   z)PersonAdmin.reset_number_ai_analysis_view   s    	Q^^''9'5F %)!+/((,%"op$A&++N}"~ $G,Fi[$YZZ "" 	QNN7oi[@P$QR'0N(OPP	Qr   c                     |j                   sy|j                  st        d      S t        d|j                   g      }t        d||j                        S )zNDisplay a reset button for AI analysis on the individual person's change page.z2Save the person first to enable AI analysis reset.zM<span style="color: #666; font-style: italic;">No AI analysis to reset</span>z#admin:bazi_person_reset_ai_analysisr   uo  <a href="{}" class="button" style="background-color: #dc3545; color: white; padding: 8px 12px; text-decoration: none; border-radius: 4px; font-size: 13px; display: inline-block; margin-top: 5px;" onclick="return confirm('Are you sure you want to reset the AI analysis for {}? This will clear all analysis data and allow regeneration.');">🗑️ Reset AI Analysis</a>)pkr   r   r   r   ro   rp   	reset_urls      r   r=   z$PersonAdmin.reset_ai_analysis_button   sV    vvG_  AQ	, HH
 	
r&   zReset BaZi AI Analysisc                     |j                   sy|j                  st        d      S t        d|j                   g      }t        d||j                        S )zUDisplay a reset button for Number AI analysis on the individual person's change page.z9Save the person first to enable Number AI analysis reset.zT<span style="color: #666; font-style: italic;">No Number AI analysis to reset</span>z*admin:bazi_person_reset_number_ai_analysisr   u  <a href="{}" class="button" style="background-color: #dc3545; color: white; padding: 8px 12px; text-decoration: none; border-radius: 4px; font-size: 13px; display: inline-block; margin-top: 5px;" onclick="return confirm('Are you sure you want to reset the Number AI analysis for {}? This will clear all Number analysis data and allow regeneration.');">🗑️ Reset Number AI Analysis</a>)r   r   r   r   r   r   s      r   r?   z+PersonAdmin.reset_number_ai_analysis_button   s[    vvN%%f  HPSPVPVxX	3 HH
 	
r&   zReset Number AI Analysisc                     |j                   sy|j                   j                   d|j                   j                   j                         }|sd}t	        d||j                   j
                        S )z3Display the created_by user's name and phone numberzUnknown User zNo Namez=<strong>{}</strong><br><small style="color: #666;">{}</small>)r0   
first_name	last_namestripr   phone)ro   rp   	full_names      r   r+   zPersonAdmin.created_by_display   se    ~~! ~~0013>>3K3K2LMSSU	!IKNN  
 	
r&   zAdded Byr6   c                     |j                   dk(  rt        d      S |j                   dk(  rt        d      S |j                   dk(  rt        d      S y)z&Format the analysis status with colors	completedu0   <span style="color: green;">✓ Completed</span>pendingu/   <span style="color: orange;">⟳ Pending</span>r   u*   <span style="color: red;">✗ Error</span>zNot Analyzed)r    r   )ro   rp   s     r   r-   z#PersonAdmin.analysis_status_display  sS    +-QRR  I-PQQ  G+KLL!r&   zAnalysis Statusc           
         |j                   sy	 |j                   }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  r|j                  j                  d	      nd}g }	|rt	        |t
              r	 t        j                  |      }
t	        |
t              rd
ddddddddd	}|
j                         D ]m  \  }}|s	t        |      j                         s#|j                  ||      }t        |      }t        |      dkD  r|dd dz   }|	j                  d| d| d       o n6t        |      }t        |      dkD  r|dd dz   }|	j                  d| d       nt	        |t              rd
ddddddddd	}|j                         D ]m  \  }}|s	t        |      j                         s#|j                  ||      }t        |      }t        |      dkD  r|dd dz   }|	j                  d| d| d       o n|	j                  d        |r6t        |      }t        |      d!kD  r|dd! dz   }|	j                  d"| d#       |r t        |      }|	j                  d$| d#       d%| d&| d'| d(}dj                  |	      |z   }t        d)| d      S # t        j                  $ r9 t        |      }t        |      dkD  r|dd dz   }|	j                  d| d       Y w xY w# t         $ r}t#        d*t        |            cY d}~S d}~ww xY w)+zFFormat the AI analysis in a readable way similar to person_detail.htmlzNo analysis availablebazi_analysisr[   providerUnknownmodelpromptthink%Y-%m-%d %H:%M:%Su   性格分析u   生活结构与平衡u   事业与财富展望u   人际关系与兼容性u   健康考量u   人生轨迹u   当前影响u   特殊元素u   实用建议)	personality_analysislife_structurecareer_wealthrelationshipshealthlife_trajectorycurrent_influencesspecial_elementspractical_recommendations,  N...z
                                    <div style="margin-bottom: 15px; padding: 10px; border-left: 3px solid #007cba; background-color: #f8f9fa;">
                                        <h4 style="margin: 0 0 8px 0; color: #007cba; font-size: 14px;">^</h4>
                                        <div style="font-size: 12px; line-height: 1.4;">R</div>
                                    </div>
                                  0<div style="font-size: 12px; line-height: 1.4;"></div>z
                            <div style="margin-bottom: 15px; padding: 10px; border-left: 3px solid #007cba; background-color: #f8f9fa;">
                                <h4 style="margin: 0 0 8px 0; color: #007cba; font-size: 14px;">V</h4>
                                <div style="font-size: 12px; line-height: 1.4;">B</div>
                            </div>
                        zH<div style="color: #666;">No structured analysis content available</div>i   u  
                    <div style="margin-bottom: 15px; padding: 10px; border-left: 3px solid #17a2b8; background-color: #e7f3ff;">
                        <h4 style="margin: 0 0 8px 0; color: #17a2b8; font-size: 14px;">🧠 AI思考过程</h4>
                        <div style="font-size: 11px; line-height: 1.4; font-family: monospace; white-space: pre-wrap; max-height: 200px; overflow-y: auto; background-color: #f8f9fa; padding: 8px; border-radius: 3px;">z2</div>
                    </div>
                u  
                    <div style="margin-bottom: 15px; padding: 10px; border-left: 3px solid #28a745; background-color: #e8f5e8;">
                        <h4 style="margin: 0 0 8px 0; color: #28a745; font-size: 14px;">📝 分析提示词</h4>
                        <div style="font-size: 11px; line-height: 1.4; font-family: monospace; white-space: pre-wrap; max-height: 400px; overflow-y: auto; background-color: #f8f9fa; padding: 8px; border-radius: 3px;">z
                <div style="margin-top: 20px; padding: 10px; background-color: #e9ecef; border-radius: 4px;">
                    <div style="font-size: 11px; color: #6c757d;">
                        <strong>Provider:</strong> 5<br>
                        <strong>Model:</strong> 9<br>
                        <strong>Generated:</strong> z?
                    </div>
                </div>
            z<div style="max-width: 800px;">z><span style="color: red;">Error displaying analysis: {}</span>)r   re   r   strftime
isinstancer   jsonloadsdictitemsr   lenappendJSONDecodeErrorjoinr   r   r   )ro   rp   analysis_dataanalysis_contentr   r   r   thinking	timestamphtml_sectionsanalysis_objsection_titles_mappingkeycontenttitlecontent_strthinking_contentprompt_contentmetadata_html	full_htmlr   s                        r   r<   zPersonAdmin.ai_analysis_display  s    *I	iOOM  -00"E$((Y?H!%%gy9E"&&x4F$(("5HPSPfPf..778KLluIM  J/?$E-m#'::.>#?L!,5 5C.E-D-G&4/=2@0>9G
2. -9,>,>,@LC&3w<+=+=+?(>(B(B3(L /2'l#&{#3c#92=ds2Ce2KK - 4 4 :iinho pYYdXe f!6$ !% -A$ #&&6"7w<#-&-dsme&;G%,,/_`g_hhn-op ,d3 -;&=%<%?,'5*8(61?
*& %5$:$:$<LC3w<#5#5#7 6 : :3 D '*'l{+c1*5ds*;e*CK%,, 2aaf`g hQQ\P] ^.  %=" $$%op #&x= '(3.'7'='E$$$ *Z [k  Zl l&  !$V$$ *Z [i  Zj j& !4 5=: >116 855>K @M .>I>ykPQQ_ ++ m!"23G7|c)")$3-%"7!((+[\c[ddj)klmb  	i_adefaghh	is^   B#L" 3A	K =K BK 5L" L" +C'L" A	LL" LL" "	M
+M?M
M
c           	         |j                   sy	 |j                   }|j                  dd      }|j                  dd      }|j                  dd      }|j                  r|j                  j                  d      nd}g }|rt	        |t
              r	 t        j                  |      }t	        |t              rdd	d
dddddd}	|j                         D ]m  \  }
}|s	t        |      j                         s#|	j                  |
|
      }t        |      }t        |      dkD  r|dd dz   }|j                  d| d| d       o n6t        |      }t        |      dkD  r|dd dz   }|j                  d| d       nt	        |t              rdd	d
dddddd}	|j                         D ]m  \  }
}|s	t        |      j                         s#|	j                  |
|
      }t        |      }t        |      dkD  r|dd dz   }|j                  d| d| d       o n6t        |      }t        |      dkD  r|dd dz   }|j                  d| d       d| d| d| d }t        d!dj                  |       | d      S # t        j                  $ r9 t        |      }t        |      dkD  r|dd dz   }|j                  d| d       Y ww xY w# t         $ r}t#        d"t        |            cY d}~S d}~ww xY w)#z/Format the Number AI analysis in a readable wayzNo Number analysis availablenumber_analysisr[   r   r   r   r   u   数字含义u   个人洞察u   生活模式u   数字学指导u   实际应用u   能量分析u	   兼容性u   建议)number_meaningpersonal_insightslife_patternsnumerological_guidancepractical_applicationsenergy_analysiscompatibilityrecommendationsr   Nr   z
                                    <div style="margin-bottom: 15px; padding: 10px; border-left: 3px solid #28a745; background-color: #f8f9fa;">
                                        <h4 style="margin: 0 0 8px 0; color: #28a745; font-size: 14px;">r   r   r   r   r   z
                            <div style="margin-bottom: 15px; padding: 10px; border-left: 3px solid #28a745; background-color: #f8f9fa;">
                                <h4 style="margin: 0 0 8px 0; color: #28a745; font-size: 14px;">r   r   z
                <div style="background-color: #f8f9fa; padding: 10px; margin-top: 10px; border-radius: 4px; border-left: 3px solid #28a745;">
                    <small style="color: #666;">
                        <strong>Provider:</strong> r   r   zA
                    </small>
                </div>
            z<div style="max-width: 600px;">zE<span style="color: red;">Error displaying Number analysis: {}</span>)r   re   rP   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )ro   rp   r   r   r   r   r   r   r   r   r   r   r   r   r   r   s                   r   r>   z&PersonAdmin.number_ai_analysis_display  s   %%1j	p22M  -001BBG$((Y?H!%%gy9EWZWtWt55>>?RS  {DIM  J/?$E,m#'::.>#?L!,5 /=1?-;6G6D/=-8/7	2. -9,>,>,@LC&3w<+=+=+?(>(B(B3(L /2'l#&{#3c#92=ds2Ce2KK - 4 4 :iinho pYYdXe f!6$ !% -A$ #&&6"7w<#-&-dsme&;G%,,/_`g_hhn-op ,d3 '5)7%3.?.<'5%0'/	*& %5$:$:$<LC3w<#5#5#7 6 : :3 D&)'l{+c1*5ds*;e*CK%,, 2aaf`g hQQ\P] ^.  %= ./w<#%%dsme3G$$'WX_W``f%gh!4 5=: >116 855>K @M >rww}?U>VWdVeeklmmg ++ m!"23G7|c)")$3-%"7!((+[\c[ddj)klmj  	pfhklmhnoo	ps^   A?K AI5 I5 2BI5 64K +K B/K 5A	K>K  KK 	K,K'!K,'K,c                     |j                   st        d      S |j                  }|dk(  rt        d      S |dk(  rt        d      S |dk(  rt        d      S |dk(  rt        d	      S t        d
      S )z,Display BaZi report status with color coding+   <span style="color: #666;">无举报</span>r   D   <span style="color: orange; font-weight: bold;">⏳ 待处理</span>reviewedF   <span style="color: blue; font-weight: bold;">👁️ 已审核</span>r\   C   <span style="color: green; font-weight: bold;">✅ 已解决</span>r]   B   <span style="color: gray; font-weight: bold;">❌ 已忽略</span>/   <span style="color: red;">🚩 已举报</span>)r3   r   r1   ro   rp   statuss      r   r.   z&PersonAdmin.bazi_report_status_display  s~    ))LMM''Yeffz!ghhz!dee{"cddPQQr&   u   BaZi举报状态c                     |j                   st        d      S |j                  }|dk(  rt        d      S |dk(  rt        d      S |dk(  rt        d      S |dk(  rt        d	      S t        d
      S )z.Display Number report status with color codingr   r   r   r   r   r\   r   r]   r   r   )r4   r   r2   r   s      r   r/   z(PersonAdmin.number_report_status_display'  s~    ++LMM))Yeffz!ghhz!dee{"cddPQQr&   u   数字举报状态c                 8   ddl m} d}|j                  dd      D ]  }d|_        |j                  |_        |j                         |_        |j                  g d       |d	z  }|j                  rV	 dd
l
m} |j                  r=|j                  j                  r' ||j                  |dd|j                         d|_	         | j!                  |d| d       y# t        $ r5}| j!                  |d|j"                   dt%        |              Y d}~d}~ww xY w)z-Admin action to mark BaZi reports as resolvedr   rY   Tr   )r3   r1   r\   )r1   rA   rB   rg   r!   r
   r^   r`   %Report resolved but email failed for r   N
   已解决 u    个BaZi分析举报)rb   rZ   filterr1   ri   rA   rj   rB   r#   rg   rk   r_   r0   rl   rR   r   r   r   r   ro   r   r   rZ   updatedr   r_   r   s           r   rF   z PersonAdmin.resolve_bazi_reports:  s   )ooTV_o`F(2F%-4\\F*-5\\^F*KK 'K 
 qLG ;;pK((V->->-D-D9"--vvz6KiKi DH@' a. 	'Zy8L#MN ! p%%g1VW]WbWbVccefijkflem/noops   3AC	D$+DDu   解决选中的BaZi举报c                 6   ddl m} d}|j                  dd      D ]  }d|_        |j                  |_        |j                         |_        |j                  sP	 ddl	m
} |j                  r=|j                  j                  r' ||j                  |dd|j                         d|_        |j%                  g d       |dz  } | j                  |d| d       y# t        $ r5}| j                  |d	|j                    d
t#        |              Y d}~kd}~ww xY w)z/Admin action to mark Number reports as resolvedr   rY   Tr   )r4   r2   r\   r^   ra   r   r   N)r2   rD   rE   rh   r!   r
   r   u    个数字分析举报)rb   rZ   r   r2   ri   rD   rj   rE   rh   rk   r_   r0   rl   rV   r   r   r   r   r#   r   s           r   rG   z"PersonAdmin.resolve_number_reportsX  s   )ootZcodF*4F'/6||F,/7||~F, ==pK((V->->-D-D9"--vxVMmMm FJB KK 'K 
 qLG- e0 	'Zy8N#OP ! p%%g1VW]WbWbVccefijkflem/noops   AC	D#+DDu   解决选中的数字举报)__name__
__module____qualname__list_displaylist_filtersearch_fieldsreadonly_fieldsr   r%   actions	fieldsetsrn   r{   r~   r   r=   short_descriptionr?   r+   admin_order_fieldr-   r<   r>   r.   r/   rF   rG   __classcell__)rw   s   @r   r(   r(   #   s    uL fK ^M BO#%68NPhiG 
v
 	 
6
 	 
r
 	 
  O 
 	 
! E$#
 	 
# S$%
 	 
@
 	+I4I7V""[&[&
& 2J.
& 9S#5
 ,6(+C(	" 1B-Ni` -?)opb 4H0R  4F0R  6J 2O8 .I*Q: 0M,,r&   r(   )django.contribr   django.utils.htmlr   django.utils.safestringr   django.urlsr   r   django.httpr   r	   r   modelsr   r   r   r%   register
ModelAdminr(    r&   r   <module>r	     sq      ) - % , #  	Z *@  &
~ 'P  #Q	M%"" Q	M Q	Mr&   