package kz.com.aman.kassa

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.os.Build
import android.widget.Toast
import androidx.annotation.NonNull
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 io.flutter.plugins.GeneratedPluginRegistrant
import kz.com.aman.kassa.bank.JsonForExternalCall
import kz.com.aman.kassa.bank.OperationType


class MainActivity : FlutterActivity() {
    private val externalApplicationRequestCode = 207
    private val externalOperationTypeKey = "ru.m4bank.ExternalApplication.OperationTypeKey"
    private val externalInputDataKey = "ru.m4bank.ExternalApplication.InputDataKey"
    private val externalResultDataKey = "ru.m4bank.ExternalApplication.ResultDataKey"

    private val bankChannel = "channel:com.amanKassa/bank"

    private lateinit var _result: MethodChannel.Result

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        //MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this))

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, bankChannel).setMethodCallHandler { call, result ->
            _result = result
            when (call.method) {
                "pay" -> {
                    operationPayment(call)
                }
                "refund" -> {
                    operationRefund(call)
                }
                "reversal" -> {
                    operationReversal(call)
                }
                "closeDay" -> {
                    operationCloseDay(call)
                }
                "version" -> {
                    result.success(Build.VERSION.SDK_INT.toString())
                }
                else -> {
                    result.notImplemented()
                }
            }
        }
    }

//    private fun getOperationList(call: MethodCall) {
//        val token: String = call.argument<String>("token").toString()
//        val operationParameters = createOperationParameters(token)
//        startOperation(OperationType.OPERATIONS_LIST,
//                JsonForExternalCall.getOperationsListJson(operationParameters.authToken))
//
//    }

    private fun operationPayment(call: MethodCall) {
        val token = call.argument<String>("token").toString()
        var amount: Long = 0
        if (call.argument<Long>("amount") != null) {
            amount = call.argument<Long>("amount")!!.toLong()
        }
        val operationParameters = createOperationParameters(token)
        val packageName = call.argument<String>("packageName").toString()

        startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()), packageName)
    }

    private fun operationRefund(call: MethodCall) {
        val token = call.argument<String>("token").toString()
        val terminalId = call.argument<String>("terminalId").toString()
        val operDay = call.argument<String>("operDay").toString()
        val transNum = call.argument<String>("transNum").toString()
        val amount = call.argument<String>("amount").toString()
        val packageName = call.argument<String>("packageName").toString()
        val operationParameters = createOperationParameters(token)
        val body = JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount)
        startOperation(
            OperationType.REFUND,
            body,
            packageName
        )
    }

    private fun operationReversal(call: MethodCall) {
        val token = call.argument<String>("token").toString()
        val terminalId = call.argument<String>("terminalId").toString()
        val operDay = call.argument<String>("operDay").toString()
        val transNum = call.argument<String>("transNum").toString()
        val operationParameters = createOperationParameters(token)
        val packageName = call.argument<String>("packageName").toString()
        val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum)
        startOperation(
            OperationType.REVERSAL,
            body,
            packageName
        )
    }

    private fun operationCloseDay(call: MethodCall) {
        val token = call.argument<String>("token").toString()
        val packageName = call.argument<String>("packageName").toString()
        val operationParameters = createOperationParameters(token)
        startOperation(
            OperationType.CLOSE_DAY,
            JsonForExternalCall.getCloseDayJson(operationParameters.authToken),
            packageName
        )
    }


    private fun createOperationParameters(token: String, operDay: String = "", terminalId: String = "", transNum: String = ""): OperationParameters {
        return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum)
    }

    private fun startOperation(
        operationType: OperationType,
        inputJsonData: String?,
        packageName: String
    ) {
        try {
            val intent = Intent()
            intent.component = ComponentName(packageName, "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
            // intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
            intent.putExtra(externalOperationTypeKey, operationType.code)
            intent.putExtra(externalInputDataKey, inputJsonData)

            if (intent.resolveActivity(packageManager) != null) {
                startActivityForResult(intent, externalApplicationRequestCode)
            } else {
                _result.error("008", "Не удалось найти подходящее приложение", "aaa")
            }
        } catch (e: ActivityNotFoundException) {
            _result.error("008", "Не удалось найти подходящее приложение", "aaa")
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        try {
        if (requestCode == externalApplicationRequestCode) {
            println("---------------")
            println(requestCode)
            println(resultCode)
            println(data)
            if (data != null) {
                println(data.getStringExtra(externalResultDataKey))
            }
            println("---------------")
            if (requestCode == externalApplicationRequestCode && resultCode == Activity.RESULT_OK && data != null) {
                println(data.getStringExtra(externalResultDataKey))
                //Toast.makeText(this, data.getStringExtra(externalResultDataKey), Toast.LENGTH_LONG).show()
                _result.success(data.getStringExtra(externalResultDataKey))
            } else {
                _result.error("008", "Error while apps connecting", "aaa")
                //Toast.makeText(this, "Error while apps connecting", Toast.LENGTH_SHORT).show()
            }
//            if (resultCode == Activity.RESULT_OK) {
//                _result.success(data?.getStringExtra("result"))
//            } else if (resultCode == Activity.RESULT_CANCELED) {
//                _result.error("008", "123","aaa")
//            } else
//                _result.success(null)
        }
        } catch (e: IllegalStateException) {
            print("IllegalStateException")
        }

    }


}

data class OperationParameters(val authToken: String, val terminalId: String, val operDay: String, val transNum: String)