package com.example.example

import android.content.Intent
import com.google.gson.Gson
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import uz.myid.android.sdk.capture.*
import uz.myid.android.sdk.capture.model.OrganizationDetails
import java.util.*

class MainActivity : FlutterActivity(), MyIdResultListener {

    private lateinit var flutterResult: MethodChannel.Result

    private val myIdClient = MyIdClient()

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                if (call.method == "runSDK") {
                    flutterResult = result

                    startMyId(call)
                }
            }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == MYID_REQUEST_CODE) {
            myIdClient.handleActivityResult(resultCode, this)
        }
    }

    override fun onSuccess(result: MyIdResult) {
        val resultData = ResultData(
            resultCode = result.code,
            comparison = result.comparison
        )
        flutterResult.success(Gson().toJson(resultData))
    }

    override fun onError(e: MyIdException) {
        val resultData = ResultData(
            errorMessage = e.message,
            errorCode = e.code
        )
        flutterResult.success(Gson().toJson(resultData))
    }

    override fun onUserExited() {
        val resultData = ResultData(
            errorMessage = "User exited",
            errorCode = 400
        )
        flutterResult.success(Gson().toJson(resultData))
    }

    private fun startMyId(call: MethodCall) {
        val phoneNumber = call.argument<String>(Keys.PHONE_NUMBER).orEmpty()
        val clientId = call.argument<String>(Keys.CLIENT_ID).orEmpty()
        val passportData = call.argument<String>(Keys.PASSPORT_DATA).orEmpty()
        val dateOfBirth = call.argument<String>(Keys.DATE_OF_BIRTH).orEmpty()
        val sdkHash = call.argument<String>(Keys.SDK_HASH).orEmpty()
        val externalId = call.argument<String>(Keys.EXTERNAL_ID).orEmpty()
        val threshold = call.argument<Double>(Keys.THRESHOLD) ?: 0.5f

        val buildMode = when (call.argument<String>(Keys.BUILD_MODE)?.uppercase()) {
            MyIdBuildMode.DEBUG.name -> MyIdBuildMode.DEBUG
            else -> MyIdBuildMode.PRODUCTION
        }
        val entryType = when (call.argument<String>(Keys.ENTRY_TYPE)?.uppercase()) {
            MyIdEntryType.FACE.name -> MyIdEntryType.FACE
            else -> MyIdEntryType.AUTH
        }
        val cameraShape = when (call.argument<String>(Keys.CAMERA_SHAPE)?.uppercase()) {
            MyIdCameraShape.ELLIPSE.name -> MyIdCameraShape.ELLIPSE
            else -> MyIdCameraShape.CIRCLE
        }

        val locale = call.argument<String>(Keys.LOCALE) ?: "en"
        val withPhoto = call.argument<Boolean>(Keys.WITH_PHOTO) ?: false

        val organizationDetails = OrganizationDetails(phoneNumber = phoneNumber)

        val myIdConfig = MyIdConfig.builder(clientId = clientId)
            .withPassportData(passportData)
            .withBirthDate(dateOfBirth)
            .withSdkHash(sdkHash)
            .withExternalId(externalId)
            .withThreshold(threshold.toFloat())
            .withBuildMode(buildMode)
            .withEntryType(entryType)
            .withLocale(Locale(locale))
            .withCameraShape(cameraShape)
            .withOrganizationDetails(organizationDetails)
            .withPhoto(withPhoto)
            .build()

        myIdClient.startActivityForResult(this, MYID_REQUEST_CODE, myIdConfig)
    }

    companion object {
        private const val CHANNEL = "flutter.native/myid"
        private const val MYID_REQUEST_CODE = 999
    }
}
