import 'dart:io';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:pdf_image_renderer/pdf_image_renderer.dart';
import 'package:scanbot_sdk/scanbot_sdk.dart';
import 'package:scanbot_sdk/scanbot_sdk_ui_v2.dart' hide IconButton, EdgeInsets;

/// Scan document as PDF
Future<Uint8List> scanDocAsPDF() async {
  var configuration = DocumentScanningFlow(
    appearance: DocumentFlowAppearanceConfiguration(
      statusBarMode: StatusBarMode.DARK,
    ),
    cleanScanningSession: true,
    outputSettings: DocumentScannerOutputSettings(pagesScanLimit: 1),
    screens: DocumentScannerScreens(
      review: ReviewScreenConfiguration(enabled: false),
    ),
  );
  var documentResult = await ScanbotSdkUiV2.startDocumentScanner(configuration);

  if (documentResult.status != OperationStatus.OK) {
    throw Exception("Scanner failed with status ${documentResult.status}");
  }

  // Convert result to PDF
  var result = await ScanbotSdk.document.createPDFForDocument(
    PDFFromDocumentParams(
      documentID: documentResult.data!.uuid,
      pdfConfiguration: PdfConfiguration(),
    ),
  );
  final pdfPath = result.pdfFileUri.replaceFirst("file://", "");
  return File(pdfPath).readAsBytes();
}

/// Render PDF to image bits
Future<Uint8List> renderPdf({String? path, Uint8List? pdfBytes}) async {
  assert(path != null || pdfBytes != null);

  // Create temporary file if required
  var isTemp = false;
  if (path == null) {
    path = p.join(
      (await getTemporaryDirectory()).absolute.path,
      "render-${Random().nextInt(10000).toString()}+.pdf",
    );

    await File(path).writeAsBytes(pdfBytes!);
    isTemp = true;
  }

  try {
    final pdf = PdfImageRenderer(path: path);
    await pdf.open();
    await pdf.openPage(pageIndex: 0);

    // get the render size after the page is loaded
    final size = await pdf.getPageSize(pageIndex: 0);

    // get the actual image of the page
    final img = await pdf.renderPage(
      pageIndex: 0,
      x: 0,
      y: 0,
      width: size.width,
      // you can pass a custom size here to crop the image
      height: size.height,
      // you can pass a custom size here to crop the image
      scale: 1,
      // increase the scale for better quality (e.g. for zooming)
      background: Colors.white,
    );

    // close the page again
    await pdf.closePage(pageIndex: 0);

    // close the PDF after rendering the page
    pdf.close();

    return img!;
  } finally {
    if (isTemp) {
      await File(path).delete();
    }
  }
}
