import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:image/image.dart' as img;
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import '../utils/logger.dart';

class ImageProcessingService {
  /// Processes an image for OCR/AI extraction:
  /// 1. Compresses the original image to reduce memory usage
  /// 2. Converts to grayscale
  /// 3. Increases contrast
  /// 4. Saves as high-quality JPEG
  static Future<File?> processInvoiceImage(File originalImage) async {
    try {
      AppLogger.print('Started processing image: ${originalImage.path}');

      // Step 1: Initial compression using flutter_image_compress (Native, fast)
      final dir = await getTemporaryDirectory();
      final compressedPath = path.join(
          dir.path, 'compressed_${DateTime.now().millisecondsSinceEpoch}.jpg');

      final XFile? compressedXFile =
          await FlutterImageCompress.compressAndGetFile(
        originalImage.path,
        compressedPath,
        quality: 85,
        minWidth: 1920,
        minHeight: 1080,
      );

      if (compressedXFile == null) {
        AppLogger.error('Failed to compress image initially', null);
        return originalImage; // Fallback to original
      }

      File compressedFile = File(compressedXFile.path);

      // Step 2: Grayscale and Contrast using `image` package (in Isolate to avoid UI freeze)
      final processedBytes =
          await compute(_applyFilters, await compressedFile.readAsBytes());

      if (processedBytes == null) {
        AppLogger.error('Failed to apply filters', null);
        return compressedFile; // Fallback to just compressed
      }

      // Step 3: Save final processed image
      final finalPath = path.join(
          dir.path, 'processed_${DateTime.now().millisecondsSinceEpoch}.jpg');
      final finalFile = File(finalPath);
      await finalFile.writeAsBytes(processedBytes);

      AppLogger.print('Finished processing image: ${finalFile.path}');
      return finalFile;
    } catch (e, stack) {
      AppLogger.error('Error processing image', e, stack);
      return originalImage; // Fallback
    }
  }

  /// Runs in an isolate to prevent UI freezing
  static List<int>? _applyFilters(List<int> bytes) {
    try {
      img.Image? decodedImage = img.decodeImage(Uint8List.fromList(bytes));
      if (decodedImage == null) return null;

      // Convert to Grayscale
      img.grayscale(decodedImage);

      // Increase contrast (adjust as needed, e.g., 1.5)
      img.contrast(decodedImage, contrast: 150);

      // Encode back to JPG
      return img.encodeJpg(decodedImage, quality: 90);
    } catch (e) {
      return null;
    }
  }
}
