import { useState, useEffect, useRef } from 'react' import { useDebounce } from './use-debounce' import { useAiConsent } from '@/components/legal/ai-consent-provider' import { countPlainWords, MIN_WORDS_FOR_AUTO_TITLE } from '@/lib/text/plain-text' export interface TitleSuggestion { title: string confidence: number reasoning?: string } interface UseTitleSuggestionsProps { content: string enabled?: boolean } export function useTitleSuggestions({ content, enabled = true }: UseTitleSuggestionsProps) { const { requestAiConsent, hasAiConsent } = useAiConsent() const [suggestions, setSuggestions] = useState([]) const [isAnalyzing, setIsAnalyzing] = useState(false) const [error, setError] = useState(null) const abortRef = useRef(null) // Debounce content by 2s to avoid excessive API calls const debouncedContent = useDebounce(content, 2000) useEffect(() => { if (!enabled || !debouncedContent) { setSuggestions([]) return } // Compter le texte visible, pas les balises de l’éditeur if (countPlainWords(debouncedContent) < MIN_WORDS_FOR_AUTO_TITLE) { setSuggestions([]) return } // Cancel previous request abortRef.current?.abort() const controller = new AbortController() abortRef.current = controller const generateTitles = async () => { if (!hasAiConsent) { const consented = await requestAiConsent() if (!consented) { setSuggestions([]) return } } setIsAnalyzing(true) setError(null) try { const response = await fetch('/api/ai/title-suggestions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: debouncedContent }), signal: controller.signal, }) if (controller.signal.aborted) return if (!response.ok) { setSuggestions([]) if (response.status !== 400) { setError('Failed to generate title suggestions') } return } const data = await response.json() setSuggestions(data.suggestions || []) } catch (err: any) { if (err.name === 'AbortError') return console.error('Title suggestions error:', err) setSuggestions([]) setError('Failed to generate title suggestions') } finally { if (!controller.signal.aborted) { setIsAnalyzing(false) } } } generateTitles() }, [debouncedContent, enabled, hasAiConsent, requestAiConsent]) // Cleanup on unmount useEffect(() => { return () => { abortRef.current?.abort(); }; }, []); return { suggestions, isAnalyzing, error, clearSuggestions: () => setSuggestions([]) } }