package com.develop.food.base.utils

import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.widget.ImageView
import androidx.annotation.IntDef
import com.develop.food.base.manager.WifiLevel
import com.develop.food.base.manager.WifiManager.getWifiLevel
import com.develop.food.base.timer.TimeTaskManager

class NetWorkManager {

    private var wifiManager: WifiManager? = null
    private var netType = 0
    private var signalStrengthTimeTask = SignalStrengthTimeTask()

    private object IN {
        val M = NetWorkManager()
    }

    companion object {
        const val SYS_CHANGE_TIME = 991
        const val SYS_CHANGE_NET_STATE = 992
        const val SYS_CHANGE_HOUR = 993
        fun get(): NetWorkManager {
            return IN.M
        }

        //没有网络连接
        const val NETWORK_NONE = 0
        const val NETWORK_DISCONNECTED = 1 //有网，但没有连接成功

        const val NETWORK_UNKNOW = 2

        //wifi连接
        const val NETWORK_WIFI = 11
        const val NETWORK_ETHERNET = 16
        const val NETWORK_MOBILE = 21

    }


    private var curSignalStrength = WifiLevel.NONE
    private var mListeners: HashSet<OnSysChangeListener> = HashSet(5)

    interface OnSysChangeListener {
        @IntDef(SYS_CHANGE_NET_STATE)
        @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
        annotation class Define

        /**
         * @param manager
         */
        fun onChange(manager: NetWorkManager?, @Define type: Int)
    }

    fun addTimeChangeListener(listener: OnSysChangeListener) {
        mListeners.add(listener)
    }

    fun removeTimeChangeListener(listener: OnSysChangeListener) {
        mListeners.remove(listener)
    }


    private var mMainHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            mListeners.apply {
                if (size > 0) {
                    val listenrs: Iterator<OnSysChangeListener> = iterator()
                    while (listenrs.hasNext()) {
                        listenrs.next().onChange(this@NetWorkManager, msg.arg1)
                    }
                }
            }
        }
    }

    /**
     * 网络变化
     */
    class NetWorkReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (ConnectivityManager.CONNECTIVITY_ACTION == intent.action) {
                get().notifyNetChange()
            }
        }
    }

    private fun notifyNetChange() {
        mMainHandler.obtainMessage(1, SYS_CHANGE_NET_STATE, 0).sendToTarget()
    }


    /**
     * 统一显示网络状态
     *
     * @param TargetView
     */
    fun showNetWorkView(TargetView: ImageView) {
        val manager = this
        if (!manager.hasNet()) {
            TargetView.isEnabled = false
            TargetView.isActivated = false
            TargetView.isSelected = false
            TargetView.isPressed = false
        } else {
            if (manager.hasWifiNetwork()) {
                showWifiStrengthIcon(TargetView)
            } else {
                TargetView.isEnabled = false
                TargetView.isPressed = false
                TargetView.isActivated = false
                TargetView.isSelected = true
            }
        }
    }

    /**
     * 是否有WIFI网络
     *
     * @return true or false
     */
    fun hasWifiNetwork(): Boolean {
        return netType == NETWORK_WIFI
    }

    /**
     * 获取当前网络连接类型
     *
     * @param context
     * @return
     */
    @SuppressLint("MissingPermission")
    fun getNetworkState(context: Context): Int {
        //获取系统的网络服务
        val connManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                ?: return NETWORK_NONE
        //如果当前没有网络
        val mobNetInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
        val wifiNetInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
        val ethNetInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET)
        val activeNetInfo = connManager.activeNetworkInfo
        if (mobNetInfo != null && wifiNetInfo != null && ethNetInfo != null) {
            if (!mobNetInfo.isConnected && !wifiNetInfo.isConnected && !ethNetInfo.isConnected) {
                return NETWORK_DISCONNECTED
            }
        }
        return if (activeNetInfo == null || !activeNetInfo.isAvailable) {
            NETWORK_NONE
        } else when (activeNetInfo.type) {
            ConnectivityManager.TYPE_WIFI -> NETWORK_WIFI
            ConnectivityManager.TYPE_ETHERNET -> NETWORK_ETHERNET
            ConnectivityManager.TYPE_MOBILE -> NETWORK_MOBILE
            else -> NETWORK_UNKNOW
        }
    }


    /**
     * 是否有网
     *
     * @return true or false
     */
    fun hasNet(): Boolean {
        return netType != NETWORK_NONE && netType != NETWORK_DISCONNECTED
    }

    /**
     * 显示WiFi强度
     */
    private fun showWifiStrengthIcon(TargetView: ImageView) {
        when (curSignalStrength) {
            WifiLevel.EXTREMELY -> {
                TargetView.setImageLevel(1)
            }
            WifiLevel.LOW -> {
                TargetView.setImageLevel(2)
            }
            WifiLevel.GENERAL -> {
                TargetView.setImageLevel(3)
            }
            WifiLevel.HEIGHT -> {
                TargetView.setImageLevel(4)
            }
            else -> {
                TargetView.setImageLevel(0)
            }
        }
    }

    /**
     * 是否有有线网络
     *
     * @return true or false
     */
    fun hasWiredNetwork(): Boolean {
        return netType == NETWORK_ETHERNET
    }

    /**
     * 定时检查wifi/4G 信号
     */
    private inner class SignalStrengthTimeTask : TimeTaskManager.Task {
        override val tag: String
            get() = "signal_strength_timer"
        override val initDelaySecs: Int
            get() = 0
        override val periodSecs: Int
            get() = 2

        override fun run() {
            if (!hasWiredNetwork()) {
                val rssi = getConnectedWifiRssi()
                val level = getWifiLevel(rssi)
                curSignalStrength = level
                notifyNetChange()
            }
        }
    }

    fun stopTask() {
        TimeTaskManager.get().removeSECLevelTask(signalStrengthTimeTask)
    }

    fun init(context: Context) {
        wifiManager = context.applicationContext
            .getSystemService(Context.WIFI_SERVICE) as WifiManager
        GlobalApp().registerReceiver(
            NetWorkReceiver(),
            IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        )
        TimeTaskManager.get().addSECLevelTask(signalStrengthTimeTask)
        netType = getNetworkState(GlobalApp())
        TimeTaskManager.get().start()
    }

    fun getConnectedWifiRssi(): Int {
        val info = wifiManager!!.connectionInfo
        var strength = 0
        if (info != null) {
            strength = info.rssi
        }
        return strength
    }
}