import { Injectable, Logger } from '@nestjs/common';
import { createWorker, Worker } from 'tesseract.js';
import { I18nService } from '../i18n/i18n.service';

@Injectable()
export class OcrService {
    private readonly logger = new Logger(OcrService.name);

    constructor(private readonly i18n: I18nService) { }

    async extractTextFromImage(imageBuffer: Buffer): Promise<string> {
        this.logger.log(`Starting OCR extraction from image (${imageBuffer.length} bytes)...`);

        // Create worker for this request to ensure stability
        let worker: any = null;
        try {
            worker = await createWorker('chi_sim+eng+jpn');

            const { data: { text } } = await worker.recognize(imageBuffer);
            this.logger.log(`OCR extraction completed. ${text.length} characters extracted.`);

            if (text.length === 0) {
                this.logger.warn('OCR returned empty text.');
            }

            await worker.terminate();
            return text.trim();
        } catch (error) {
            this.logger.error(`OCR text extraction failed: ${error.message}`);
            if (worker) {
                try { await worker.terminate(); } catch (e) { }
            }
            throw new Error(this.i18n.formatMessage('ocrFailed', { message: error.message }));
        }
    }

    async extractTextWithConfidence(imageBuffer: Buffer): Promise<{
        text: string;
        confidence: number;
    }> {
        this.logger.log(`Starting OCR extraction with confidence (${imageBuffer.length} bytes)...`);

        let worker: any = null;
        try {
            worker = await createWorker('chi_sim+eng+jpn');
            const { data } = await worker.recognize(imageBuffer);
            this.logger.log(`OCR extraction completed. Confidence: ${data.confidence}%`);

            await worker.terminate();
            return {
                text: data.text.trim(),
                confidence: data.confidence,
            };
        } catch (error) {
            this.logger.error(`OCR text extraction failed: ${error.message}`);
            if (worker) {
                try { await worker.terminate(); } catch (e) { }
            }
            throw new Error(this.i18n.formatMessage('ocrFailed', { message: error.message }));
        }
    }
}
