import type { OcrBlock } from "./layout.ts";

interface CanvasWithDimensions {
  width: number;
  height: number;
}

export async function createTesseractRecognizer(
  onProgress: (event: { status: string; progress: number }) => void = () => undefined,
) {
  const { createWorker } = await import("tesseract.js");
  const worker = await createWorker(["chi_sim", "eng"], 1, {
    logger(message) {
      onProgress({ status: message.status, progress: message.progress });
    },
  });
  await worker.setParameters({ preserve_interword_spaces: "1" });

  return {
    async recognize(
      image: CanvasWithDimensions & Tesseract.ImageLike,
    ): Promise<{ width: number; height: number; blocks: OcrBlock[] }> {
      const result = await worker.recognize(
        image,
        {},
        { blocks: true, text: true },
      );
      const blocks: OcrBlock[] = (result.data.blocks ?? [])
        .flatMap((block) => block.paragraphs)
        .map((paragraph) => ({
          text: paragraph.text,
          x: paragraph.bbox.x0,
          y: paragraph.bbox.y0,
          width: paragraph.bbox.x1 - paragraph.bbox.x0,
          height: paragraph.bbox.y1 - paragraph.bbox.y0,
          confidence: paragraph.confidence,
        }));
      return { width: image.width, height: image.height, blocks };
    },
    async terminate(): Promise<void> {
      await worker.terminate();
    },
  };
}
