import { useState } from "react"; interface EntityMapping { originalValue: string; anonymizedValue: string; entityType: string; startIndex: number; endIndex: number; } // Nouvelle interface pour les résultats de Presidio Analyzer interface PresidioAnalyzerResult { entity_type: string; start: number; end: number; score: number; analysis_explanation?: { recognizer: string; pattern_name?: string; pattern?: string; validation_result?: boolean; }; } // Interface pour la réponse de l'API interface ProcessDocumentResponse { text?: string; anonymizedText?: string; piiCount?: number; analyzerResults?: PresidioAnalyzerResult[]; error?: string; } interface AnonymizationLogicProps { sourceText: string; fileContent: string; uploadedFile: File | null; setOutputText: (text: string) => void; setError: (error: string | null) => void; setEntityMappings: (mappings: EntityMapping[]) => void; } export const useAnonymization = ({ sourceText, fileContent, uploadedFile, setOutputText, setError, setEntityMappings, }: AnonymizationLogicProps) => { const [isProcessing, setIsProcessing] = useState(false); const anonymizeData = async () => { const textToProcess = sourceText || fileContent || ""; if (!textToProcess.trim()) { setError( "Veuillez saisir du texte à anonymiser ou télécharger un fichier" ); return; } setIsProcessing(true); setError(null); setOutputText(""); setEntityMappings([]); try { console.log("🚀 Début anonymisation avec Presidio"); const formData = new FormData(); if (uploadedFile) { console.log("📁 Traitement fichier:", { name: uploadedFile.name, type: uploadedFile.type, size: uploadedFile.size }); formData.append("file", uploadedFile); } else { console.log("📝 Traitement texte saisi"); const textBlob = new Blob([textToProcess], { type: "text/plain" }); const textFile = new File([textBlob], "input.txt", { type: "text/plain" }); formData.append("file", textFile); } console.log("🔍 Appel à /api/process-document avec Presidio..."); console.log("📦 FormData préparée:", Array.from(formData.entries())); const response = await fetch("/api/process-document", { method: "POST", body: formData, }); console.log("📡 Réponse reçue:", { ok: response.ok, status: response.status, statusText: response.statusText, headers: Object.fromEntries(response.headers.entries()) }); if (!response.ok) { let errorMessage = `Erreur HTTP: ${response.status}`; try { const responseText = await response.text(); console.log("📄 Contenu de l'erreur:", responseText); if (responseText.trim()) { try { const errorData = JSON.parse(responseText); if (errorData.error) { errorMessage = errorData.error; console.log("✅ Message détaillé récupéré:", errorMessage); } } catch (jsonError) { console.error("❌ Erreur parsing JSON:", jsonError); // ✅ Utiliser la variable console.error("❌ Réponse non-JSON:", responseText); errorMessage = `Erreur ${response.status}: Réponse invalide du serveur`; } } } catch (readError) { console.error("❌ Impossible de lire la réponse:", readError); } throw new Error(errorMessage); } const data: ProcessDocumentResponse = await response.json(); console.log("📊 Réponse API:", data); if (data.error) { throw new Error(data.error); } if (data.anonymizedText) { console.log("✅ Anonymisation réussie avec Presidio"); setOutputText(data.anonymizedText); // Extraire les mappings depuis les résultats Presidio (plus d'erreur 'any') if (data.analyzerResults && data.text) { const mappings: EntityMapping[] = data.analyzerResults.map( (entity: PresidioAnalyzerResult, index: number) => ({ originalValue: data.text!.substring(entity.start, entity.end), anonymizedValue: `[${entity.entity_type}${index + 1}]`, entityType: entity.entity_type, startIndex: entity.start, endIndex: entity.end, }) ); setEntityMappings(mappings); console.log("📋 Entités détectées:", mappings.length); console.log("🔍 Détails des entités:", mappings); } } else if (data.text) { console.log( "⚠️ Fallback: Presidio non disponible, texte original retourné" ); setOutputText(data.text); setError("Presidio temporairement indisponible. Texte non anonymisé."); } } catch (error) { console.error("❌ Erreur anonymisation complète:", error); setError( error instanceof Error ? error.message : "Erreur lors de l'anonymisation avec Presidio" ); } finally { setIsProcessing(false); } }; return { anonymizeData, isProcessing }; };