package com.alva.flutter.plugin.qrscanner

import androidx.annotation.NonNull;

import android.app.Activity
import android.content.Intent
import android.graphics.Color
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.Registrar
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import com.google.zxing.client.android.CaptureActivity
import com.google.zxing.client.android.Intents
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding

/** QrScannerPlugin */
public class QrScannerPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel: MethodChannel
  private lateinit var activity: Activity
  private var result: Result? = null

  private val requestCode: Int = 0

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.flutterEngine.dartExecutor, "scanner")
    channel.setMethodCallHandler(this);
  }

  // This static function is optional and equivalent to onAttachedToEngine. It supports the old
  // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
  // plugin registration via this function while apps migrate to use the new Android APIs
  // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
  //
  // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
  // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
  // depending on the user's project. onAttachedToEngine or registerWith must both be defined
  // in the same class.
  companion object {
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val channel = MethodChannel(registrar.messenger(), "scanner")
      val instance = QrScannerPlugin()
      instance.activity = registrar.activity()
      registrar.addActivityResultListener(instance)
      channel.setMethodCallHandler(instance)
    }
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "scan") {
      val intent = Intent(activity, CaptureActivity::class.java)
      intent.action = Intents.Scan.ACTION;
      if(call.hasArgument(Intents.Scan.SCAN_TITLE))
        intent.putExtra(Intents.Scan.SCAN_TITLE, call.argument<String>(Intents.Scan.SCAN_TITLE))
      else
        intent.putExtra(Intents.Scan.SCAN_TITLE, "二维码扫描")
      if(call.hasArgument(Intents.Scan.LASER_COLOR))
        intent.putExtra(Intents.Scan.LASER_COLOR, Color.parseColor(call.argument<String>(Intents.Scan.LASER_COLOR)))
      if(call.hasArgument(Intents.Scan.KEY_PLAY_BEEP))
        intent.putExtra(Intents.Scan.KEY_PLAY_BEEP, call.argument<Boolean>(Intents.Scan.KEY_PLAY_BEEP))
      if(call.hasArgument(Intents.Scan.PROMPT_MESSAGE))
        intent.putExtra(Intents.Scan.PROMPT_MESSAGE, call.argument<String>(Intents.Scan.PROMPT_MESSAGE))
      if(call.hasArgument(Intents.Scan.ERROR_MESSAGE))
        intent.putExtra(Intents.Scan.ERROR_MESSAGE, call.argument<String>(Intents.Scan.ERROR_MESSAGE))
      if(call.hasArgument(Intents.Scan.PERMISSION_DENIED_MESSAGE))
        intent.putExtra(Intents.Scan.PERMISSION_DENIED_MESSAGE, call.argument<String>(Intents.Scan.PERMISSION_DENIED_MESSAGE))
      if(call.hasArgument(Intents.Scan.MESSAGE_CONFIRM_TEXT))
        intent.putExtra(Intents.Scan.MESSAGE_CONFIRM_TEXT, call.argument<String>(Intents.Scan.MESSAGE_CONFIRM_TEXT))
      if(call.hasArgument(Intents.Scan.MESSAGE_CANCEL_TEXT))
        intent.putExtra(Intents.Scan.MESSAGE_CANCEL_TEXT, call.argument<String>(Intents.Scan.MESSAGE_CANCEL_TEXT))
      activity.startActivityForResult(intent, requestCode)
      this.result = result
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: android.content.Intent?): Boolean {
    if (requestCode == requestCode && resultCode == Activity.RESULT_OK) {
      result?.success(data?.getStringExtra(Intent.EXTRA_TEXT) ?: "")
      return true
    }
    return false
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    activity = binding.activity
    binding.addActivityResultListener(this)
  }

  override fun onDetachedFromActivity() {
  }

  override fun onDetachedFromActivityForConfigChanges() {
  }

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
  }
}
