import { useCallback, type MouseEvent } from "react"; import type { ScanDetailsModalProps } from "../types"; import type { ParsedArtifactCandidate } from "../../../../../lib/artifactOcrParser"; export interface ScanDetailsModalModel { closeDetails: () => void; stopPropagation: (event: MouseEvent) => void; parsedNotes: string[]; showParsedNotes: boolean; cropRows: Array<{ id: string; dataUrl: string; label: string; x: number; y: number; width: number; height: number }>; ocrRows: Array<{ id: string; label: string; confidence: number; text: string }>; debugText: string; showCrops: boolean; showOcr: boolean; } interface UseScanDetailsModalModelInput { setDetailsOpen: ScanDetailsModalProps["setDetailsOpen"]; parsedArtifact: ScanDetailsModalProps["controller"]["parsedArtifact"]; latestCapture: ScanDetailsModalProps["latestCapture"]; } export function useScanDetailsModalModel({ setDetailsOpen, parsedArtifact, latestCapture, }: UseScanDetailsModalModelInput): ScanDetailsModalModel { const closeDetails = useCallback(() => setDetailsOpen(false), [setDetailsOpen]); const stopPropagation = useCallback((event: MouseEvent) => { event.stopPropagation(); }, []); const parsedNotes = (parsedArtifact?.notes ?? []) as ParsedArtifactCandidate["notes"]; const crops = latestCapture?.crops ?? []; const ocr = latestCapture?.ocr ?? []; const cropRows = crops .filter((crop) => Boolean(crop.dataUrl)) .map((crop) => ({ id: crop.id, dataUrl: crop.dataUrl ?? "", label: crop.label, x: crop.rect.x, y: crop.rect.y, width: crop.rect.width, height: crop.rect.height, })); return { closeDetails, stopPropagation, parsedNotes, showParsedNotes: parsedNotes.length > 0, cropRows, ocrRows: ocr.map((entry) => ({ id: entry.id, label: entry.label, confidence: entry.confidence, text: entry.text || "No text detected", })), debugText: `Debug: crops ${crops.length} / ocr ${ocr.length}`, showCrops: cropRows.length > 0, showOcr: ocr.length > 0, }; }