
    qh\                         d dl 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
 ej                  ej                         d Zd Zd Zd Zd	 Zd
 Zd ZddddZd ZddZd Zy)    N)settings)Image)api_keyc                 Z   | syg d}t        |       }|D ])  }t        j                  |d|t        j                        }+ t        j                  d|      }|r	 t        |j                  d            dfS dd|  dfS # t        $ r#}dd	|j                  d       d
| fcY d}~S d}~ww xY w)z0Extract numeric amount from string with currency)        zEmpty amount string)u   [₹$€£¥]z'\b(INR|USD|EUR|GBP|JPY|Rs\.?|Rupees?)\bz[,\s] )flagsz(\d+\.?\d*)   Nr   zCould not convert 'z' to float: zNo numeric value found in '')strresub
IGNORECASEsearchfloatgroup
ValueError)
amount_strpatterns_to_removecleanedpatternnumber_matches         C/var/www/html/ai-insurance-compliance-backend/pdf_analysis/utils.pyextract_amount_from_stringr      s    ) *oG% D&&"gR]]CD 99^W5L	U++A./55 -j\;;;  	U-l.@.@.C-DLQRPSTTT	Us   A> >	B*B%B*%B*c                 X  ' | j                  dd      }t        |      \  }}|rt        d|        ddd| dddgddd	S |dk  rddd
| dddgddd	S 	 t        j                  d      }d|j                  dd       d|j                  dd       d|j                  dd       d|j                  dd       d|j                  dg        d|j                  dg        d| j                  dd       d| j                  dd       d| d | d!| j                  dg        d"| j                  dg        d#|r|d$d% nd& d'|r|d$d% nd& d(}|j                  |      }	|	j                  j                         }
|
j                  d)d      j                  d*d      j                         }
	 |
j                  d+      }|
j                  d,      d-z   }|d.k(  s||k  rt        d/      |
|| }t        j                  |      }|j                  d0i       }|j                  d1i       }|j                  d2i       }|j                  d3i       }|j                  d4i       }|j                  d5d      }|j                  d6d      }d7|j                  d8d      z
  }|j                  d9d      }t        ||z   |z   |z   d:z        }i d;|j                  d<d      d=|d>|j                  d?d@      dA|j                  dBd      d5|dC|j                  dDg       dE|j                  dFg       d6|dG|j                  dGg       d1|j                  dHd      dI|j                  dIdJ      dK|j                  dKg       dL|j                  dLg       dM|j                  dMd      dN|j                  dNg       dO|j                  dOg       dP|j                  dPdQ      |j                  dRd      |
dSS # t        j                  t        f$ rV}|
j!                         't#        'fdTdUD              }dV'v xr dW'v}dX'v xr dY'v}|xr |xr | dZd[|d\gdQ|
d]cY d$}~S d$}~ww xY w# t$        $ r}t        d^|        t'        |j                  dg       D cg c]   }|j!                         j                         " nc c}w c}      }t'        | j                  dg       D cg c]   }|j!                         j                         " nc c}w c}      } t'        |j                  dg       D !cg c]   }!|!j!                         j                         " nc c}!w c}!      }"t'        | j                  dg       D !cg c]   }!|!j!                         j                         " nc c}!w c}!      }#| |z
  }$|#|"z
  }%t)        |$      dk(  xr t)        |%      dk(  }d7|cxk  xr d_k  nc }&|xr |&|r|&rd`ndadb| dc|& |t+        |$      t+        |%      z   ddg|$s|%rt+        |$      t+        |%      z   ng z   |r|&rdendQddfcY d$}~S d$}~ww xY w)gzLUse AI to validate if the bill amount is reasonable and matches prescriptiontotalAmount0zAmount extraction error: Fr   zAmount extraction failed: r   zInvalid amount format)amount_reasonableamount_scoreai_reasoningprescription_matchprice_analysisfraud_indicatorssuggested_rangeraw_ai_responsezInvalid amount: zZero or negative amountgemini-1.5-flashz
        You are a medical billing fraud detection expert. Analyze this prescription vs bill for compliance and fraud detection.
        
        PRESCRIPTION DATA:
        - Patient: patientName	Not foundz
        - Doctor: 
doctorNamez
        - Date: datez
        - Ailment: ailmentNot specifiedz#
        - Prescribed Medications: medicationsz
        - Prescribed Tests: testsz1
        
        BILL DATA:
        - Hospital: hospitalNamez
        - Bill Date: billDatez
        - Total Amount: u    (₹z )
        - Billed Medications: z
        - Billed Tests: z8
        
        ORIGINAL TEXTS:
        Prescription: Ni   zNo textz
        Bill: u6  
        
        ANALYZE THE FOLLOWING:
        
        1. PRESCRIPTION COMPLIANCE:
        - Are ALL billed medications actually prescribed?
        - Are ALL billed tests actually prescribed?
        - Are there any extra items billed that weren't prescribed?
        
        
        2. FRAUD DETECTION:
        - Items not matching prescription?
        - Quantity manipulation?
        
        3. MEDICAL NECESSITY:
        - Are the prescribed items appropriate for the ailment?
        - Any unnecessary expensive items?
        
        Respond with ONLY this JSON (no extra text):
        {
            "prescription_compliance": {
                "all_items_prescribed": true/false,
                "compliance_score": 0-100,
                "prescribed_but_not_billed": ["items"],
                "billed_but_not_prescribed": ["items"],
                "explanation": "detailed analysis"
            },
        
            "fraud_detection": {
                "fraud_risk": "LOW/MEDIUM/HIGH",
                "fraud_score": 0-100,
                "fraud_indicators": ["list of red flags"],
                "duplicate_items": ["items"],
                "explanation": "fraud analysis"
            },
            "medical_necessity": {
                "medically_appropriate": true/false,
                "necessity_score": 0-100,
                "unnecessary_items": ["items"],
                "missing_essential_items": ["items"],
                "explanation": "medical necessity analysis"
            },
            "overall_assessment": {
                "bill_valid": true/false,
                "overall_score": 0-100,
                "recommended_action": "APPROVE/INVESTIGATE/REJECT",
                "suggested_fair_amount": "₹XXXX",
                "summary": "brief overall assessment"
            }
        }
        ```json```{}r
   zNo valid JSON found in responseprescription_compliancer#   fraud_detectionmedical_necessityoverall_assessmentcompliance_scoreprice_scored   fraud_scorenecessity_score   r   
bill_validr    r!   summaryzNo summary providedr"   all_items_prescribedextra_items_billedbilled_but_not_prescribedmissing_prescribed_itemsprescribed_but_not_billedoverpriced_itemsexplanation
fraud_riskUNKNOWNr$   duplicate_itemsmedically_appropriateunnecessary_itemsmissing_essential_itemsrecommended_actionINVESTIGATEsuggested_fair_amount)rR   r&   c              3   &   K   | ]  }|v  
 y w)N ).0wordai_lowers     r   	<genexpr>z*validate_amount_with_ai.<locals>.<genexpr>   s     &tDtx'7&ts   )fraud
suspiciousoverchargedextra
prescribedznot prescribed
reasonable
overpriced2   z9JSON parsing failed. Fallback analysis based on keywords.zAI response parsing failed)r   r    r!   r"   r$   rP   r&   zAI validation error: iP  K      z+AI failed. Basic check: Prescription match=z, Amount reasonable=zAI validation failedAPPROVE)r   r    r!   r"   rD   r$   rP   r&   )getr   printgenaiGenerativeModelgenerate_contenttextstripreplacefindrfindr   jsonloadsintJSONDecodeErrorlowerany	Exceptionsetlenlist)(	bill_dataprescription_data	bill_textprescription_textr   amount	error_msgmodelpromptresponseai_analysis
json_startjson_endjson_str	ai_resultr7   r#   r8   r9   r:   r;   r<   r>   r?   final_score
json_errorhas_fraud_indicatorsprescription_matchesprice_reasonabler   medprescribed_medsbilled_medstestprescribed_testsbilled_tests
extra_medsextra_testsr   rW   s(                                          @r   validate_amount_with_air   )   s    }c2J2:>FI))56!&8D"' !8 9!!	
 		
 {!&.vh7"' !: ;!!	
 		
@
%%&89 &))-EF G$(({CD E"&&v{;< =%)))_EF G##4#8#8#K"L M.227B?@ A ]]>;?@ AmmJ<= >#E& 2(}}]B?@ A"w34 5 3D(#.S T"+y#; 2<	)FP ))&1mm))+
 ")))R8@@KQQSP	$))#.J"((-1HR8z#9 !BCC":h7H

8,I
 '0mm4Mr&R#&]]+;R@N'mm,=rBO ).A2 F!*/CR!H  7::;MqQ(,,]A>K 3 3M1 EEK/334EqIO/+=Ko]abbcK#%7%;%;L%%P  2 6 6yBW X %&=&A&ABXZ_&` #$4 %&=&A&AB]_a&b +,C,G,GHceg,h { #N$6$67I2$N !."4"4]B"G$ o11,	J%& #O$7$78JB$O'( "?#6#67H"#M). ():)>)>?VX])^/0 $%6%:%:;NPR%S12 *+<+@+@AZ\^+_38 %&8&<&<=QS`&a9: *<)?)?@WY[)\#.= B $$j1 	
 #((*H $'&tDs&t#t #/8#;#`@PX`@` +x7XLPX<X &:%k>N%kWkSk ""[&:%A$B&3#. 	,  
%aS)* >O>S>STace>fgssyy{002ggh)--WY:Z[3399;,,.[[\ARAVAVW^`bAcd

 2 2 4ddeY]]7TV=WXTDJJL..0XXY !?2
"%55":!3MK8HA8M62U2 "6!K:K#7<MBTVIJ^I__s  uF  tG  H"6"&z"2T+5F"F!7 8dnr}D<LtT_O`<`  DF  !G0DIZ)an!	
 		
!
s|   EQ "H9O Q5AQ QQ QQ 
X)'X$?%R%
$&X$
%S0
/&X$%T;
:&X$ %V
BX$X)$X)c                     d}	 t        j                  |       }|j                  D ]  }||j                         z  } |S # t        $ r}t        d|        Y d}~yd}~ww xY w)z#Extract text from uploaded PDF filer   zError extracting PDF text: N)PyPDF2	PdfReaderpagesextract_textrt   re   )pdf_fileri   
pdf_readerpager   s        r   extract_text_from_pdfr     sl    D%%h/
$$ 	(DD%%''D	( +A3/0s   :? 	A AA c                 V   t        j                  d      }d}t        j                  t	        j
                  | j                                     }|j                  ||g      }|j                  j                         j                  dd      j                  dd      j                         }|S )z;Use Gemini Vision to read image and return structured JSON.r'   zjread this data with details summary and return only valid JSON dictionary. No explanations, just raw JSON.r2   r   r3   )rf   rg   r   openioBytesIOreadrh   ri   rj   rk   )
image_filer~   r   	pil_imageresultri   s         r   #extract_text_from_image_with_geminir     s    !!"45EyF 

2::joo&789I ##	F ;;&&y"5==eRHNNPDK    c                 X   	 t        j                  d      }d|  d}|j                  |      }|j                  j	                         j                  dd      j                  dd      j	                         }t        j                  |      }|S # t        $ r}dddg g dd	cY d
}~S d
}~ww xY w)z2Extract structured data from prescription using AIr'   zi
        Extract information from this prescription text and return ONLY a JSON object:
        
        a  
        
        Extract the exact information from the document. Do not make up or assume any information.
        Return this exact JSON format:
        {"patientName": "exact name from document or 'Not found'", "doctorName": "exact name from document or 'Not found'", "date": "exact date from document or 'Not found'", "medications": ["exact medication names"], "tests": ["exact test names"], "ailment": "patient condition/disease mentioned or 'Not specified'"}
        r2   r   r3   r)   r-   )r(   r*   r+   r.   r/   r,   N)	rf   rg   rh   ri   rj   rk   rn   ro   rt   ri   r   r~   r   r   	json_textr   r   s           r   parse_prescription_datar   *  s    
%%&89	 
 	 ))&1MM'')11)R@HHPRSYY[	I& 	
 '%&
 	
	
s   B
B 	B)B$B)$B)c                 r   	 t        j                  d      }d|  d}|j                  |      }|j                  j	                         j                  dd      j                  dd      j	                         }t        j                  |      }|S # t        $ r }t        d|        ddd	g g d
cY d}~S d}~ww xY w)z*Extract structured data from bill using AIr'   zi
        Extract information from this medical bill text and return ONLY a JSON object:
        
        a  
        
        Extract the exact information from the document. Do not make up or assume any information.
        Return this exact JSON format:
        {"hospitalName": "exact name from document or 'Not found'", "billDate": "exact date from document or 'Not found'", "totalAmount": "exact amount with currency or '$0.00'", "tests": ["exact test names billed"], "medications": ["exact medication names billed"]}
        r2   r   r3   zError parsing bill: r)   $0.00)r0   r1   r   r/   r.   N)
rf   rg   rh   ri   rj   rk   rn   ro   rt   re   r   s           r   parse_bill_datar   I  s    
%%&89	 
 	 ))&1MM'')11)R@HHPRSYY[	I& 
$QC()'#"
 	

s   B
B 	B6B1+B61B6c                     | sy| j                         } t        j                  dd|       } t        j                  dd|       } dj                  | j	                               } | j                         S )zGLowercase, strip units/quantities, remove bracketed info & punctuation.r   z\(.*?\)z[^a-z0-9\s] )rr   r   r   joinsplitrj   )names    r   normalize_itemr   g  sW    ::<D66*b$'D66."d+D88DJJL!D::<r   zblood sugar test)zfasting blood sugarzpostprandial blood sugarzblood sugar test fbs & ppbsc                 D    t        |       }t        j                  ||      S )z&Normalize test names and map synonyms.)r   TEST_SYNONYMSrd   )r   ns     r   normalize_testr   x  s    tAQ""r   c                    | j                  dg       D cg c]  }t        |       }}|j                  dg       D cg c]  }t        |       }}| j                  dg       D cg c]  }t        |      |v s| }}| j                  dg       D cg c]  }t        |      |vs| }}|j                  dg       D cg c]  }t        |      |vs| }	}t        |      dk(  xr t        |	      dk(  }
|r#t        t        |      t        |      z  dz        nd}| j                  dg       D cg c]  }t	        |       }}|j                  dg       D cg c]  }t	        |       }}| j                  dg       D cg c]  }t	        |      |v s| }}| j                  dg       D cg c]  }t	        |      |vs| }}|j                  dg       D cg c]  }t	        |      |vs| }}t        |      dk(  xr t        |      dk(  }|r#t        t        |      t        |      z  dz        nd}| j                  d      dvxr | j                  d      dv}|rdnd}t        || ||      }|d   }|d	   }t        ||z   |z   |z   d
z        }i d|d|d|d|d|
d|d|d|d|d|d|d|d|d|	d|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 )zECalculate basic validation scores with fuzzy matching for meds/tests.r.   r   r=   r/   r(   )r)   r   Nr*   r   r    r@   prescriptionValidprescriptionScore
testsMatch
testsScoremedicationsMatchmedicationsScoreamountReasonableamountScoreai_amount_analysisoverallScorematchedMedicationsmatchedTestsunmatchedPrescriptionMedsunmatchedBillMedsunmatchedPrescriptionTestsunmatchedBillTests)rd   r   rv   rp   r   r   )ry   rx   r{   rz   mpres_meds_normbill_meds_normmatched_medsunmatched_pres_medsunmatched_bill_medsmedications_matchmedications_scoretpres_tests_normbill_tests_normmatched_testsunmatched_pres_testsunmatched_bill_teststests_matchtests_scoreprescription_validprescription_scoreamount_validationr   r    overall_scores                             r   "calculate_basic_validation_resultsr   ~  s    2C1F1F}VX1YZAnQ'ZNZ1:}b1QRAnQ'RNR044]BGo!>Z[K\`nKnAoLo&7&;&;M2&NzR`abRckyRy1zz&/mmM2&Fr.YZJ[cqJq1rr/0A5W#>Q:RVW:WP^S.^1DDKLde 3D2G2GQS2TUQ~a(UOU2;--2LMQ~a(MOM 1 5 5gr Bk1nUVFW[jFjQkMk'8'<'<Wb'Iv!^\]M^fuMuAvv'0}}Wb'An!^TUEV^mEmAnn*+q0SS9M5NRS5SKL[#s=)C,@@CGHabK 	m,4KK 	Kl+3JJ  !3 0	;LiYjk)*=>$^4L +k9<MMP\\`aabM// 	k 	k	
 	- 	- 	- 	| 	/ 	 	l 	 	$%8 	0 	%&:  	2! K [Rozr VMkvns^   KK%K8KK%K?KK1K!K&K+K+.K0K0K5.K5c                 L   	 t        j                  d      }d| j                  dd       d| j                  dd       d| j                  dd       d	| j                  d
d       d| j                  dg        d| j                  dg        d|j                  dd       d|j                  dd       d|j                  dd       d|j                  dg        d|j                  dg        d| d| d}|j                  |      }|j                  j                         j                  dd      j                  dd      j                         }t        j                  |      }|S # t        $ r9}	t        d|	        d d!d"d#d d!d"d$d d!d"d%d&d!d"gd'd(g g d)gd*d!d+d,cY d-}	~	S d-}	~	ww xY w).zHAI-based intelligent validation considering medical context and ailmentsr'   z
        You are a medical expert AI. Analyze the following prescription and bill for medical accuracy and fraud detection.

        PRESCRIPTION DATA:
        Patient: r(   r)   z
        Doctor: r*   z
        Date: r+   z
        Ailment/Condition: r,   r-   z!
        Prescribed Medications: r.   z
        Prescribed Tests: r/   z'

        BILL DATA:
        Hospital: r0   z
        Bill Date: r1   z
        Total Amount: r   r   z
        Billed Medications: z
        Billed Tests: z.

        ORIGINAL PRESCRIPTION TEXT:
        z&

        ORIGINAL BILL TEXT:
        a  

        Please analyze and provide intelligent validation considering:
        1. Are the prescribed medications appropriate for the ailment?
        2. Are the prescribed tests relevant for the condition?
        3. Are the billed items medically justified?
        4. Is the billing amount reasonable for the services?
        5. Are there any red flags or fraud indicators?
        6. Are there missing essential medications/tests for the condition?
        7. Are there unnecessary medications/tests billed?
        8. NO need for price analysis, just focus on medical accuracy for fraud detection.

        Respond in this exact JSON format:
        {
            "medicalAccuracy": {
                "prescriptionAppropriate": true/false,
                "prescriptionScore": 0-100,
                "reasoning": "explanation"
            },
            "billAccuracy": {
                "billJustified": true/false,
                "billScore": 0-100,
                "reasoning": "explanation"
            },
            "crossValidation": {
                "itemsMatch": true/false,
                "matchScore": 0-100,
                "reasoning": "explanation"
            },
            "fraudDetection": {
                "fraudRisk": "LOW/MEDIUM/HIGH",
                "fraudScore": 0-100,
                "indicators": ["list of concerns"],
                "reasoning": "explanation"
            },
            "recommendations": {
                "missingItems": ["items that should be present"],
                "unnecessaryItems": ["items that seem unnecessary"],
                "suggestions": ["general recommendations"]
            },
            "overallIntelligentScore": 0-100,
            "summary": "brief summary of analysis"
        }
        r2   r   r3   z!Error in intelligent validation: Fr   zAnalysis failed)prescriptionAppropriater   	reasoning)billJustified	billScorer   )
itemsMatch
matchScorer   rK   zAI analysis failed)	fraudRisk
fraudScore
indicatorsr   zPlease retry analysis)missingItemsunnecessaryItemssuggestionsz2Intelligent analysis failed due to technical error)medicalAccuracybillAccuracycrossValidationfraudDetectionrecommendationsoverallIntelligentScorerB   N)rf   rg   rd   rh   ri   rj   rk   rn   ro   rt   re   )
ry   rx   r{   rz   r~   r   r   r   r   r   s
             r   (calculate_intelligent_validation_resultsr     s,   k
%%&89 $''{CD E"&&|[AB C $$V[9: ;-11)_MN O!!2!6!6}b!I J K,00"=> ? ===> ?MM*k:; < }}]G<= >&]]="=> ? }}Wb12 3	 
 	 
 +	-AF ))&1MM'')11)R@HHPRSYY[	I& 
1!56 ,1%&.  "'. $.  '011	 !#$& 78 
 ()K9
 	

s   EE! !	F#*.FF#F#)r   r   )r   google.generativeaigenerativeairf   django.confr   PILr   r   rn   r   	configureGOOGLE_API_KEYr   r   r   r   r   r   r   r   r   r   r   rT   r   r   <module>r      sx     #    	  	 // 0
<4c
J

>
< . 2#5#:|m
r   