package com.ejada.hmg.hmgwifi

import android.content.Context
import android.net.ConnectivityManager
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.util.Log
import android.widget.Toast
import com.ejada.hmg.MainActivity
import com.ejada.hmg.utils.FlutterText
import com.ejada.hmg.utils.HMGUtils


class HMG_Guest(context: MainActivity) {
    private var wifiManager: WifiManager? = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager?
    private var connectivityManager: ConnectivityManager? = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    private var context = context

    private val TAG = "HMG_Guest"
    private val TEST = false
    private var SSID = """"HMG-MobileApp""""

    private lateinit var completionListener: ((status: Boolean, message: String) -> Unit)

    fun completionOnUiThread(status: Boolean, message: String){
        completionListener(status, message)
    }

    /*
	 * Helpful:
	 * http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically
	 */
    fun connectToHMGGuestNetwork(completion: (status: Boolean, message: String) -> Unit) {
        wifiManager?.let { wm ->
            completionListener = completion

            if (!wm.isWifiEnabled){
                wm.isWifiEnabled = true
                HMGUtils.popFlutterText(context,"enablingWifi");
                HMGUtils.timer(2000,false){
                    connect()
                }
            }else{
                connect()
            }

        }

    }


    private fun connect(){
        val security = "OPEN"
        val networkPass = ""
        Log.d(TAG, "Connecting to SSID \"$SSID\" with password \"$networkPass\" and with security \"$security\" ...")

        // You need to create WifiConfiguration instance like this:
        val conf = WifiConfiguration()
        conf.SSID = SSID
        conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
        conf.networkId = ssidToNetworkId(SSID)

        val wm = wifiManager!!

        if (conf.networkId == -1) {
            wm.addNetwork(conf)
        } else {
            Log.v(TAG, "WiFi found - updating it.\n")
            wm.updateNetwork(conf)
        }

        conf.networkId = ssidToNetworkId(SSID)
        Log.d(TAG, "Network ID: ${conf.networkId}")

        val networkIdToConnect =  conf.networkId
        if (networkIdToConnect >= 0) {
            Log.v(TAG, "Start connecting to $SSID Wifi...")

            // We disable the network before connecting, because if this was the last connection before
            // a disconnect(), this will not reconnect.
            wm.disableNetwork(networkIdToConnect)
            val result = wm.enableNetwork(networkIdToConnect, true)
            if(result){
                HMGUtils.timer(8000,false){
                    if(wm.getConnectionInfo().getSSID() == SSID){
                        completionOnUiThread(true, "successConnectingHmgNetwork")

                    }else{
                        errorConnecting()
                    }
                }

            }else{
                errorConnecting()
            }



        }else{
            Log.v(TAG, "Cannot connect to $SSID network")
            errorConnecting()
        }
    }

    private fun errorConnecting(){
        completionOnUiThread(false, "errorConnectingHmgNetwork")
    }

    // If CompileSDK is greater and equals to APILevel 29
    private fun connectNewer(wm:WifiManager){

//            Log.e(TAG, "connection wifi  Q")
//
//            val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
//                    .setSsid(ssid)
//                    .setWpa2Passphrase(password)
//                    .build()
//
//            val networkRequest: NetworkRequest = NetworkRequest.Builder()
//                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
//                    .setNetworkSpecifier(wifiNetworkSpecifier)
//                    .build()
//
//            var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
//            var networkCallback = object : ConnectivityManager.NetworkCallback() {
//                override fun onAvailable(network: Network) {
//                    super.onAvailable(network)
//                    connectivityManager.bindProcessToNetwork(network)
//                    Log.e(TAG, "onAvailable")
//                }
//
//                override fun onLosing(network: Network, maxMsToLive: Int) {
//                    super.onLosing(network, maxMsToLive)
//                    Log.e(TAG, "onLosing")
//                }
//
//                override fun onLost(network: Network) {
//                    super.onLost(network)
//                    Log.e(TAG, "onLosing")
//                    Log.e(TAG, "losing active connection")
//                }
//
//                override fun onUnavailable() {
//                    super.onUnavailable()
//                    Log.e(TAG, "onUnavailable")
//                }
//            }
//            connectivityManager.requestNetwork(networkRequest, networkCallback)
    }


    /**
     * This method takes a given String, searches the current list of configured WiFi
     * networks, and returns the networkId for the network if the SSID matches. If not,
     * it returns -1.
     */
    private fun ssidToNetworkId(ssid: String): Int {
        val currentNetworks = wifiManager!!.configuredNetworks
        var networkId = -1

        // For each network in the list, compare the SSID with the given one
        for (test in currentNetworks) {
            if (test.SSID == ssid) {
                networkId = test.networkId
                break
            }
        }
        return networkId
    }
}