import { isSupported, recognizeText } from "expo-mlkit-ocr"; import { parseReceiptText, type ReceiptParseResult } from "@/lib/receipt-parse"; export type ReceiptOcrResult = ReceiptParseResult & { rawText: string; }; export function mlKitOcrAvailable(): boolean { try { return isSupported(); } catch { return false; } } function normalizeImageUri(uri: string): string { if (uri.startsWith("file://") || uri.startsWith("content://")) { return uri; } return `file://${uri}`; } /** Run on-device ML Kit OCR and parse receipt fields from recognized text. */ export async function recognizeReceiptFromImage(uri: string): Promise { if (!mlKitOcrAvailable()) { throw new Error("On-device OCR is not supported on this device."); } const result = await recognizeText(normalizeImageUri(uri)); const rawText = result.text?.trim() ?? ""; const parsed = parseReceiptText(rawText); return { ...parsed, rawText, }; } export function applyReceiptOcrToForm( ocr: ReceiptParseResult, current: { description: string; amountText: string; date: Date }, ): { description: string; amountText: string; date: Date; ocrText: string } { return { description: ocr.vendor?.trim() || current.description, amountText: ocr.amount != null ? String(ocr.amount) : current.amountText, date: ocr.date ?? current.date, ocrText: ocr.rawLines.join("\n"), }; }