package com.example.wabi.domain.system

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import com.example.wabi.view.screeens.connection.ConncetionDestinations
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch

class NetworkConnectivityObserver(
    private val context: Context
) : ConnectivityObserver {

    private val connectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    override fun observe(): Flow<Boolean> {
        return callbackFlow {
            val callback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    super.onAvailable(network)
                    launch {
                        send(
                            ConncetionDestinations.internetConnection
                        )
                    }
                }

                override fun onLosing(network: Network, maxMsToLive: Int) {
                    super.onLosing(network, maxMsToLive)
                    launch {
                        send(
                            ConncetionDestinations.internetConnection
                        )
                    }
                }

                override fun onLost(network: Network) {
                    super.onLost(network)
                    launch {
                        send(
                            ConncetionDestinations.noInternetConncetion
                        )
                    }
                }

                override fun onUnavailable() {
                    super.onUnavailable()
                    launch {
                        send(
                            ConncetionDestinations.noInternetConncetion
                        )
                    }
                }
            }

            connectivityManager.registerDefaultNetworkCallback(callback)
            awaitClose {
                connectivityManager.unregisterNetworkCallback(callback)
            }
        }.distinctUntilChanged()
    }
}