package com.seatel.mobilehall.ui.profile.activity

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.viewbinding.ViewBinding
import at.nineyards.anyline.AnylineDebugListener
import at.nineyards.anyline.camera.CameraController
import at.nineyards.anyline.camera.CameraOpenListener
import at.nineyards.anyline.core.RunFailure
import at.nineyards.anyline.models.AnylineImage
import com.android.volley.VolleyError
import com.google.gson.Gson
import com.seatel.mobilehall.data.network.SeatelRequest
import com.seatel.mobilehall.databinding.ActivityScanMrzBinding
import com.seatel.mobilehall.ui.profile.interactor.ScanMRZInteractor
import com.seatel.mobilehall.ui.profile.model.ScanModuleEnum
import com.seatel.mobilehall.ui.profile.presenter.ScanMRZPresenter
import com.seatel.mobilehall.util.Constant
import com.seatel.mobilehall.util.ScanMRZSharePref
import com.seatel.mobilehall.util.SeatelAlertDialog
import com.seatel.mobilehall.util.SeatelUtils
import io.anyline.plugin.id.IDFieldScanOptions
import io.anyline.plugin.id.IdScanViewPlugin
import io.anyline.plugin.id.MrzConfig
import io.anyline.plugin.id.MrzFieldScanOptions
import io.anyline.plugin.id.MrzIdentification
import io.anyline.view.ScanView
import org.json.JSONObject

class ScanMRZActivity : ScanActivity(), CameraOpenListener, AnylineDebugListener,
    ScanMRZInteractor.View {

    private val TAG: String = ScanMRZActivity::class.java.simpleName
    private lateinit var ScanMRZBinding: ActivityScanMrzBinding // ViewScanMRZBinding instance
    private lateinit var mScanMrz: ScanView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialize ViewScanMRZBinding
        ScanMRZBinding = ActivityScanMrzBinding.inflate(layoutInflater)
        setContentView(ScanMRZBinding.root)

        // Initialize ScanView
        mScanMrz = ScanMRZBinding.mrzView
        mScanMrz.setScanConfig("mrz_view_config.json")

        // Check if the MRZ key is available, if not fetch it
        if (ScanMRZSharePref.getConstant(this).scanMrzKey.isEmpty()) {
            showProgress()
            ScanMRZPresenter(this).onRequestMRZKey()
        } else {
            init(ScanMRZSharePref.getConstant(this).scanMrzKey)
            Log.d("---anyLineKey", "onGetMRZKeySucceed: ${ScanMRZSharePref.getConstant(this).scanMrzKey}")
        }

        // Handle registration type and manual input
        if (intent.getBooleanExtra("isRegisterType", false)) {
            ScanMRZBinding.textViewInputManually.visibility = View.VISIBLE
            ScanMRZBinding.textViewOr.visibility = View.VISIBLE
            ScanMRZBinding.textViewInputManually.setOnClickListener {
                setResult(Activity.RESULT_FIRST_USER)
                onBackPressed()
            }
        }

        // Close button functionality
        ScanMRZBinding.buttonClose.setOnClickListener {
            onBackPressed()
        }
    }

    override fun isDisplayToolbar(): Boolean {
        return false
    }

    private fun init(key: String) {
        val mrzConfig = MrzConfig()

        val fieldScanOption = MrzFieldScanOptions().apply {
            vizDateOfIssue = IDFieldScanOptions.FieldScanOption.DEFAULT
            vizAddress = IDFieldScanOptions.FieldScanOption.DEFAULT
            vizGivenNames = IDFieldScanOptions.FieldScanOption.DEFAULT
            vizSurname = IDFieldScanOptions.FieldScanOption.DEFAULT
            vizDateOfBirth = IDFieldScanOptions.FieldScanOption.DEFAULT
            vizDateOfExpiry = IDFieldScanOptions.FieldScanOption.DEFAULT
        }

        mrzConfig.setIdFieldScanOptions(fieldScanOption)
        mrzConfig.isStrictMode = false
        mrzConfig.enableFaceDetection(true)

        val scanViewPlugin = IdScanViewPlugin(
            applicationContext, key, mScanMrz.scanViewPluginConfig, mrzConfig
        )
        mScanMrz.scanViewPlugin = scanViewPlugin

        scanViewPlugin.addScanResultListener { idScanResult ->
            val identification = idScanResult.result as MrzIdentification
            val currentBitmap = identification.faceImage
            val newImage = AnylineImage(currentBitmap)
            val path = setupImagePath(idScanResult.fullImage)
            val facePath = setupImagePath(newImage)

            // Intent to pass scan result data
            val data = identification.toJSONObject() as JSONObject
            Log.d(TAG, "init: " + Gson().toJson(data))
            val intent = Intent().apply {
                putExtra(Constant.MRZ_FIRST_NAME, data.optString("surname"))
                putExtra(Constant.MRZ_LAST_NAME, data.optString("givenNames"))
                putExtra(Constant.MRZ_ID, data.optString("documentNumber"))
                putExtra(Constant.MRZ_DOB, data.optString("dateOfBirthObject"))
                putExtra(Constant.MRZ_GENDER, data.optString("sex"))
                putExtra(Constant.MRZ_DOCUMENT_TYPE, data.optString("documentType"))
                putExtra(Constant.MRZ_DATE_OF_EXPIRY_TYPE, data.optString("dateOfExpiry"))
                putExtra(Constant.MRZ_COUNTRY_CODE, data.optString("nationalityCountryCode"))
                putExtra("imagePath", path)
            }
            setResult(Activity.RESULT_OK, intent)
            onBackPressed()
        }
    }

    override fun onResume() {
        super.onResume()
        mScanMrz.start()
        if (ScanMRZSharePref.getConstant(this).scanMrzKey.isNotEmpty()) {
            init(ScanMRZSharePref.getConstant(this).scanMrzKey)
        }
    }

    override fun getViewBinding(): ViewBinding {
        return ActivityScanMrzBinding.inflate(layoutInflater)
    }


    override fun onPause() {
        super.onPause()
        mScanMrz.stop()
        mScanMrz.releaseCameraInBackground()
    }

    override fun getScanView(): ScanView? {
        return null
    }

    override fun getScanModule(): ScanModuleEnum.ScanModule {
        return ScanModuleEnum.ScanModule.MRZ
    }

    override fun onCameraError(p0: Exception?) {
        throw RuntimeException(p0)
    }

    override fun onCameraOpened(p0: CameraController?, width: Int, height: Int) {
        Log.d(TAG, "Camera opened successfully. Frame resolution $width x $height")
    }

    override fun onRunSkipped(runFailure: RunFailure?) {
        // Handle skipped run failure if needed
    }

    override fun onDebug(p0: String?, p1: Any?) {
        // Handle debug logs if needed
    }

    override fun onGetMRZKeyFailed(error: VolleyError) {
        hideProgress()
        SeatelAlertDialog.with(
            this,
            SeatelUtils.translatForDialog(this, SeatelRequest.getErrorMessageFrom(error))
        ).setDismiss {
            finish()
        }.show()
    }

    override fun onGetMRZKeySucceed(key: String) {
        hideProgress()
        ScanMRZSharePref.getConstant(this).scanMrzKey = key
        Log.d(TAG, "onGetMRZKeySucceed: $key")
        init(key)
    }

    companion object {
        fun launchForResult(context: Context) {
            val intent = Intent(context, ScanMRZActivity::class.java)
            (context as Activity).startActivityForResult(intent, Constant.SCAN_MRZ)
        }
    }
}
