import 'dart:convert';
import 'dart:io';

import 'package:camera/camera.dart';
import 'package:get/get.dart';
import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
import 'package:path/path.dart' as path;
import 'package:http/http.dart' as http;
import '../../main.dart';

class CameraClassController extends GetxController {
  late CameraController cameraController;
  late List<CameraDescription> cameras;
  bool isCameraInitialized = false;
  final TextRecognizer _textRecognizer = TextRecognizer();
  String? scannedText;
  bool isloading = false;

  @override
  void onInit() {
    super.onInit();
    initializeCamera();
  }

  Future<void> initializeCamera() async {
    try {
      cameras = await availableCameras();
      //update();
      cameraController = CameraController(
        cameras[0],
        ResolutionPreset.medium,
        enableAudio: false,
      );
      await cameraController.initialize();
      isCameraInitialized = true;
      update();
    } catch (e) {
      if (e is CameraException) {
        switch (e.code) {
          case 'CameraAccessDenied':
            Get.defaultDialog(
              title: 'Camera Access Denied.'.tr,
              middleText: '',
              confirm:
                  MyElevatedButton(title: 'Open Settings'.tr, onPressed: () {}),
            );
            break;
          default:
            // Handle other errors here.
            break;
        }
      }
    }
  }

  var imgUrl = '';
  Future extractCardId() async {
    // Construct the path for the image file
    final directory = await path_provider.getTemporaryDirectory();
    final imagePath =
        path.join(directory.path, '${box.read(BoxName.driverID)}.png');

    // Capture the image and save it to the specified path
    final XFile capturedImage = await cameraController.takePicture();

    // Move the captured image to the desired path
    await capturedImage.saveTo(imagePath);
    await uploadImage(File(capturedImage.path));

    extractByAPI('${AppLink.server}/card_image/' + box.read(BoxName.driverID));
  }

  Future extractByAPI(String imgUrl) async {
    var headers = {'apikey': 'K89368168788957'};
    var request = http.MultipartRequest(
        'POST', Uri.parse('https://api.ocr.space/parse/image'));
    request.fields.addAll({
      'language': 'ara',
      'isOverlayRequired': 'false',
      'url': imgUrl,
      'iscreatesearchablepdf': 'false',
      'issearchablepdfhidetextlayer': 'false'
    });

    request.headers.addAll(headers);

    http.StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      print(await response.stream.bytesToString());
    } else {
      print(response.reasonPhrase);
    }
  }

  Future<String> uploadImage(File imageFile) async {
    String? basicAuthCredentials =
        await storage.read(key: BoxName.basicAuthCredentials);
    var request = http.MultipartRequest(
      'POST',
      Uri.parse(AppLink.uploadImage),
    );

    // Attach the image file to the request
    request.files.add(
      await http.MultipartFile.fromPath('image', imageFile.path),
    ); // Add the headers to the request
    request.headers.addAll({
      "Content-Type": "application/x-www-form-urlencoded",
      'Authorization':
          'Basic ${base64Encode(utf8.encode(basicAuthCredentials.toString()))}',
    });

    // Add the driverID to the request
    request.fields['driverID'] = box.read(BoxName.driverID);
    // Send the request
    var response = await request.send();

    // Read the response
    var responseData = await response.stream.toBytes();
    var responseString = String.fromCharCodes(responseData);
    scannedText = responseString;
    update();
    // Return the link received from the server
    return responseString;
  }

  Future<void> takePictureAndMLGoogleScan() async {
    try {
      // Construct the path for the image file
      final directory = await path_provider.getTemporaryDirectory();
      final imagePath =
          path.join(directory.path, '${box.read(BoxName.driverID)}.png');

      // Capture the image and save it to the specified path
      final XFile capturedImage = await cameraController.takePicture();

      // Move the captured image to the desired path
      await capturedImage.saveTo(imagePath);

      // Recognize the text in the image
      final InputImage inputImage =
          InputImage.fromFile(File(capturedImage.path));
      final RecognizedText recognizedText =
          await _textRecognizer.processImage(inputImage);
      scannedText = recognizedText.text;

      // Extract the scanned text line by line
      final List<Map<String, dynamic>> lines = [];
      for (var i = 0; i < recognizedText.blocks.length; i++) {
        lines.add({
          'line_number': i,
          'text': recognizedText.blocks[i].text,
        });
      }

      // Convert the list of lines to a JSON string
      final String jsonOutput = jsonEncode(lines);

      update();

      // Print the JSON output
      print(jsonOutput);

      // Get.back();
    } catch (e) {
      print('Error capturing image: $e');
    }
  }

  String getTextAsJSON(String text) {
    final lines = text.split('\n');
    final jsonList = lines.map((line) {
      return {
        'line_text': line,
        'num_words': line.trim().split(' ').length,
      };
    }).toList();

    final json = {
      'lines': jsonList,
      'num_lines': lines.length,
    };

    return jsonEncode(json);
  }

  List<String> getTextBlocks(String text) {
    return text.split('\n');
  }

//   Future<void> takePictureAndTesseractScan() async {
//     try {
//       // Construct the path for the image file
//       final directory = await path_provider.getTemporaryDirectory();
//       final imagePath =
//           path.join(directory.path, '${box.read(BoxName.driverID)}.png');

//       // Capture the image and save it to the specified path
//       final XFile capturedImage = await cameraController.takePicture();

//       // Move the captured image to the desired path
//       await capturedImage.saveTo(imagePath);

//       // Recognize the text in the image
//       final languages = [
//         'eng',
//         'ara'
//       ]; // Specify the languages you want to use for text extraction

//       final text = await FlutterTesseractOcr.extractText(imagePath,
//           language: languages.join('+'), // Combine multiple languages with '+'
//           args: {
//             "psm": "4",
//             "preserve_interword_spaces": "1",
//             // "rectangle": const Rect.fromLTWH(100, 100, 200, 200),
//           } // Additional options if needed
//           );
//       isloading = false;
//       final jsonText = getTextAsJSON(text);
//       final textBlocks = getTextBlocks(text);
//       update();
//       scannedText =
//           textBlocks.toString(); // Convert the extracted text to JSON.

// // Print the JSON to the console.
//       print(jsonText);
//       update();
//       // print(text);
//     } catch (e) {
//       print('Error during text extraction: $e');
//       scannedText = '';
//     }
//   }

  @override
  void onClose() {
    cameraController.dispose();
    super.onClose();
  }
}
