import UIKit
import ScanbotSDK

@objc
public class RNScanbotDocumentScannerLegacyView: UIView  {

  @objc var vc: UIViewController?
  @objc var scannerViewController: RNScanbotDocumentScannerViewController?
  @objc var onDocumentScannerResult: RCTDirectEventBlock?
  @objc var onDetectionResult: RCTDirectEventBlock?
  private let shouldDetachScanner: Bool

  @objc
  override public init(frame: CGRect) {
    shouldDetachScanner = true
    super.init(frame: frame)
    
    vc = UIViewController()
    vc?.view = self

    scannerViewController = RNScanbotDocumentScannerViewController()
    scannerViewController?.delegate = self
    scannerViewController?.setDefaults()
  }

  @objc
  public init(frame: CGRect, delegate:SBSDKDocumentScannerViewControllerDelegate) {
    shouldDetachScanner = false
    super.init(frame: frame)

    vc = UIViewController()
    vc?.view = self

    scannerViewController = RNScanbotDocumentScannerViewController()
    scannerViewController?.delegate = delegate
    scannerViewController?.setDefaults()
  }
  
  public override func didMoveToWindow() {
    super.didMoveToWindow()
    
    if window != nil {
      attachScanner()
    } else if shouldDetachScanner {
      detachScanner()
    }
  }
  
  public override func removeFromSuperview() {
    detachScanner()
    vc = nil
    scannerViewController = nil
    super.removeFromSuperview()
  }
  
  @objc
  required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  @objc public func setAcceptedAngleScore(_ value: NSNumber?) {
    scannerViewController?.acceptedAngleScore(value)
  }

  @objc public func setAcceptedBrightnessThreshold(_ value: NSNumber?) {
    scannerViewController?.acceptedBrightnessThreshold(value)
  }

  @objc public func setAcceptedSizeScore(_ value: NSNumber?) {
    scannerViewController?.acceptedSizeScore(value)
  }

  @objc public func setAutoSnappingEnabled(_ value: Bool) {
    scannerViewController?.autoSnappingEnabled(value)
  }

  @objc public func setAutoSnappingSensitivity(_ value: NSNumber?) {
    scannerViewController?.autoSnappingSensitivity(value)
  }

  @objc public func setAutoSnappingDelay(_ value: NSNumber?) {
    scannerViewController?.autoSnappingDelay(value)
  }

  @objc public func setCameraModule(_ value: NSString?) {
    scannerViewController?.cameraModule(value)
  }

  @objc public func setCameraPreviewMode(_ value: NSString?) {
    scannerViewController?.cameraPreviewMode(value)
  }

  @objc public func setFlashEnabled(_ value: Bool) {
    scannerViewController?.flashEnabled(value)
  }

  @objc public func setIgnoreBadAspectRatio(_ value: Bool) {
    scannerViewController?.ignoreBadAspectRatio(value)
  }

  @objc public func setPhotoQualityPrioritization(_ value: NSString?) {
    scannerViewController?.photoQualityPrioritization(value)
  }

  @objc public func setRequiredAspectRatios(_ value: NSArray?) {
    scannerViewController?.requiredAspectRatios(value)
  }

  @objc public func setFinderEnabled(_ value: Bool) {
    scannerViewController?.finderEnabled(value)
  }

  @objc public func setFinderLineColor(_ value: UIColor?) {
    scannerViewController?.finderLineColor(value)
  }

  @objc public func setFinderLineWidth(_ value: NSNumber?) {
    scannerViewController?.finderLineWidth(value)
  }

  @objc public func setFinderOverlayColor(_ value: UIColor?) {
    scannerViewController?.finderOverlayColor(value)
  }

  @objc public func setFinderCornerRadius(_ value: NSNumber?) {
    scannerViewController?.finderCornerRadius(value)
  }

  @objc public func setFinderMinimumPadding(_ value: NSNumber?) {
    scannerViewController?.finderMinimumPadding(value)
  }

  @objc public func setFinderAspectRatio(_ value: NSDictionary?) {
    scannerViewController?.finderAspectRatio(value)
  }

  @objc public func setPolygonEnabled(_ value: Bool) {
    scannerViewController?.polygonEnabled(value)
  }

  @objc public func setPolygonBackgroundColor(_ value: UIColor?) {
    scannerViewController?.polygonBackgroundColor(value)
  }

  @objc public func setPolygonBackgroundColorOK(_ value: UIColor?) {
    scannerViewController?.polygonBackgroundColorOK(value)
  }

  @objc public func setPolygonColor(_ value: UIColor?) {
    scannerViewController?.polygonColor(value)
  }

  @objc public func setPolygonColorOK(_ value: UIColor?) {
    scannerViewController?.polygonColorOK(value)
  }

  @objc public func setPolygonLineWidth(_ value: NSNumber?) {
    scannerViewController?.polygonLineWidth(value)
  }

  @objc public func setPolygonCornerRadius(_ value: NSNumber?) {
    scannerViewController?.polygonCornerRadius(value)
  }

  @objc public func setPolygonAutoSnapProgressColor(_ value: UIColor?) {
    scannerViewController?.polygonAutoSnapProgressColor(value)
  }

  @objc public func setPolygonAutoSnapProgressLineWidth(_ value: NSNumber?) {
    scannerViewController?.polygonAutoSnapProgressLineWidth(value)
  }

  @objc public func setPolygonAutoSnapProgressEnabled(_ value: Bool) {
    scannerViewController?.polygonAutoSnapProgressEnabled(value)
  }

  @objc public func freezeCamera() {
    scannerViewController?.freezeCamera()
  }

  @objc public func unfreezeCamera(){
    scannerViewController?.unfreezeCamera()
  }

  @objc public func snapDocument() {
    scannerViewController?.snapDocument()
  }

  @objc public func onDidDetectDocument(documentImage: UIImage) -> String? {
    if let imageData = documentImage.jpegData(compressionQuality: 1.0) {
      let base64String = imageData.base64EncodedString()
      return base64String
    }

    return nil
  }

  @objc public func onDidDetectFrame(result: SBSDKDocumentDetectorResult?) -> String? {
    guard let result else { return nil }

    return scannerViewController?.onDocumentDetectionStatus(result: result)
  }
  
  @objc
  public func attachScanner(){
    if let scanner = scannerViewController, let vc = vc  {
      vc.sbsdk_attach(scanner, in: self)
    }
  }
  
  @objc
  public func detachScanner(){
    if let scanner = scannerViewController {
      vc?.sbsdk_detach(scanner)
      scanner.freezeCamera()
    }
  }

}

extension RNScanbotDocumentScannerLegacyView: SBSDKDocumentScannerViewControllerDelegate {

  public func documentScannerViewController(_ controller: ScanbotSDK.SBSDKDocumentScannerViewController,
                                            didSnapDocumentImage documentImage: UIImage,
                                            on originalImage: UIImage,
                                            with result: ScanbotSDK.SBSDKDocumentDetectorResult?,
                                            autoSnapped: Bool) {
    guard let onDocumentScannerResult else { return }

    guard let result = onDidDetectDocument(documentImage: documentImage) else { return }

    onDocumentScannerResult(["result" : result])
  }

  public func documentScannerViewController(_ controller: SBSDKDocumentScannerViewController,
                                            didSampleVideoFrame videoFrameImage: UIImage,
                                            detectionResult result: SBSDKDocumentDetectorResult?) {
    guard let onDetectionResult else { return }

    guard let status = onDidDetectFrame(result: result) else { return }

    onDetectionResult(["result" : status])
  }

}
