package com.ejada.hmg.utils

import android.content.Context
import android.content.Intent
import android.content.Intent.getIntent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.core.app.ActivityCompat.startActivityForResult
import android.net.wifi.WifiManager
import android.util.Log
import com.ejada.hmg.MainActivity
import com.ejada.hmg.hmgwifi.HMG_Guest
import com.ejada.hmg.geofence.GeoZoneModel
import com.ejada.hmg.geofence.HMG_Geofence
import com.ejada.hmg.hmgwifi.WpaEnterprise
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

class PlatformBridge(private var flutterEngine: FlutterEngine, private var mainActivity: MainActivity) {

    private lateinit var channel: MethodChannel

    companion object {
        private const val CHANNEL = "HMG-Platform-Bridge"
        private const val HMG_INTERNET_WIFI_CONNECT_METHOD = "connectHMGInternetWifi"
        private const val HMG_GUEST_WIFI_CONNECT_METHOD = "connectHMGGuestWifi"
        private const val ENABLE_WIFI_IF_NOT = "enableWifiIfNot"
        private const val REGISTER_HMG_GEOFENCES = "registerHmgGeofences"
        private const val UN_REGISTER_HMG_GEOFENCES = "unRegisterHmgGeofences"
        private const val IS_DRAW_OVER_APPS_PERMISSION_ALLOWED = "isDrawOverAppsPermissionAllowed"
        private const val ASK_DRAW_OVER_APPS_PERMISSION = "askDrawOverAppsPermission"
        private const val GET_INTENT = "getIntent"
    }

    fun create() {
        channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        HMGUtils.setPlatformChannel(channel)
        channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result ->

            if (methodCall.method == HMG_INTERNET_WIFI_CONNECT_METHOD) {
                connectHMGInternetWifi(methodCall, result)

            } else if (methodCall.method == HMG_GUEST_WIFI_CONNECT_METHOD) {
                connectHMGGuestWifi(methodCall, result)

            } else if (methodCall.method == ENABLE_WIFI_IF_NOT) {
                enableWifiIfNot(methodCall, result)
            } else if (methodCall.method == REGISTER_HMG_GEOFENCES) {
                registerHmgGeofences(methodCall, result)
            } else if (methodCall.method == UN_REGISTER_HMG_GEOFENCES) {
                unRegisterHmgGeofences(methodCall, result)
            } else if (methodCall.method == IS_DRAW_OVER_APPS_PERMISSION_ALLOWED) {
                isDrawOverAppsPermissionAllowed(methodCall, result)
            } else if (methodCall.method == ASK_DRAW_OVER_APPS_PERMISSION) {
                askDrawOverAppsPermission(methodCall, result)
            } else if (methodCall.method == GET_INTENT) {
                getIntentData(methodCall, result)
            } else {
                result.notImplemented()
            }

        }

        val res = channel.invokeMethod("localizedValue", "errorConnectingHmgNetwork")

    }

    private fun connectHMGInternetWifi(methodCall: MethodCall, result: MethodChannel.Result) {
        (methodCall.arguments as ArrayList<*>).let {
            require(it.size == 3 && (it[0] is String) && (it[1] is String), lazyMessage = {
                "Missing or invalid arguments (Must have three argument of 'String'"
            })

            val ssid = it[0].toString()
            val username = it[1].toString()
            val password = it[2].toString()

            WpaEnterprise(mainActivity,ssid).connect(username,password) { status, message ->
                HMGUtils.timer(2000,false){
                    mainActivity.runOnUiThread {
                        if(status)
                            result.success(if (status) 1 else 0)
                        else
                            result.error(message, null, null)
                    }
                }
            }

//            HMG_Internet(mainActivity)
//                    .connectToHMGGuestNetwork(username, password) { status, message ->
//                        mainActivity.runOnUiThread {
//                            result.success(if (status) 1 else 0)
//
//                            HMGUtils.popFlutterText(mainActivity, message)
//                            Log.v(this.javaClass.simpleName, "$status | $message")
//                        }
//
//                    }
        }
    }


    private fun connectHMGGuestWifi(methodCall: MethodCall, result: MethodChannel.Result) {
        (methodCall.arguments as ArrayList<*>).let {
            require(it.size == 1 && (it[0] is String), lazyMessage = {
                "Missing or invalid arguments (Must have one argument 'String at 0'"
            })

            val ssid = it[0].toString()
            HMG_Guest(mainActivity, ssid).connectToHMGGuestNetwork { status, message ->
                mainActivity.runOnUiThread {
                    result.success(if (status) 1 else 0)

                    HMGUtils.popFlutterText(mainActivity, message)
                    Log.v(this.javaClass.simpleName, "$status | $message")
                }
            }
        }
    }

    private fun enableWifiIfNot(methodCall: MethodCall, result: MethodChannel.Result) {
        val wm = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager?
        if (wm != null) {
            if (!wm.isWifiEnabled)
                wm.isWifiEnabled = true
            result.success(true)
        } else
            result.error("101", "Error while opening wifi, Please try to open wifi yourself and try again", "'WifiManager' service failed");
    }


    private fun registerHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) {

        channel.invokeMethod("getGeoZones", null, object : MethodChannel.Result {
            override fun success(result: Any?) {
                if (result is String) {
                    val geoZones = GeoZoneModel().listFrom(result)
                    HMG_Geofence.shared(mainActivity).register() { s, e -> }
                }
            }

            override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {}
            override fun notImplemented() {}
        })

    }

    private fun unRegisterHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) {
        HMG_Geofence.shared(mainActivity).unRegisterAll { status, exception ->
            if (status)
                result.success(true)
            else
                result.error("101", exception?.localizedMessage, exception);
        }
    }

    private fun isDrawOverAppsPermissionAllowed(methodCall: MethodCall, result: MethodChannel.Result) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (
                    Settings.canDrawOverlays(mainActivity)
            ) {
                result.success(true)
            } else {
                result.success(false)
            }
        } else {
            result.success(false)
        }
    }

    private fun askDrawOverAppsPermission(methodCall: MethodCall, result: MethodChannel.Result) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
            val uri = Uri.parse("package:" + mainActivity.getPackageName())
            intent.setData(uri)
            startActivityForResult(mainActivity, intent, 102, null)
            result.success(true)
        } else {
            result.success(false)
        }
    }

    private fun getIntentData(methodCall: MethodCall, result: MethodChannel.Result) {

        val bundle: Bundle? = getIntent("").extras
        if (bundle != null) {
            val message = bundle.getString("notification") // 1
            System.out.println("BundleExtra:" + message)
            Toast.makeText(this.mainActivity, message + "", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this.mainActivity, "Bundle Null", Toast.LENGTH_SHORT).show();
        }
        result.success(true);
    }
}
