package com.base.locationsharewhite.service

import android.annotation.SuppressLint
import android.app.NotificationManager
import android.app.job.JobInfo
import android.app.job.JobParameters
import android.app.job.JobScheduler
import android.app.job.JobService
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.location.Location
import android.os.Build
import android.os.CountDownTimer
import android.os.Looper
import androidx.work.Configuration
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.helper.MyApplication
import com.base.locationsharewhite.service.StayNotification.createPermanentNotification
import com.base.locationsharewhite.utils.LogEx
import com.base.locationsharewhite.utils.ToastUtils.toast
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.model.LatLng
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlin.random.Random


/**
 *  常驻通知栏
 */
class StayJobService : JobService() {

    init {
        val builder = Configuration.Builder()
        builder.setJobSchedulerJobIdRange(0, 1000)
    }

    private val TAG = "StayJobService"

    companion object {
        val ACTION_LOCATION_UPDATES = "ACTION_REQUEST_LOCATION_UPDATES"
        private val NOTIFICATION_PERMANENT_ID = 186
        var googleLocation: LatLng? = null

        //位置更新回调
        private var locationCallback: LocationCallback? = null

        //位置的一次性回调
        var oneShotLocationCallBack: (() -> Unit)? = null

        //更新频率
        var getGoogleServiceLocationDelay: Int = 60

        fun Context.requestServiceLocationUpdates() {
            startService(Intent(this, StayJobService::class.java).apply { action = ACTION_LOCATION_UPDATES })
        }


        private var isRunning = false
        private const val JOB_INFO_ID: Int = 101
        private const val JOB_PERIODIC: Long = 5 * 1000L
        fun Context.startJob() {
            if (isRunning) return
            val jobScheduler = getSystemService(JOB_SCHEDULER_SERVICE) as JobScheduler
            val componentName = ComponentName(this, StayJobService::class.java)
            val jobInfo = JobInfo.Builder(JOB_INFO_ID, componentName)
                .setMinimumLatency(30000)
                .build()
            jobScheduler.schedule(jobInfo)
        }

    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        LogEx.logDebug(TAG, "onStartCommand")
        if (intent?.action == ACTION_LOCATION_UPDATES) {
            LogEx.logDebug(TAG, "onStartCommand ACTION_LOCATION_UPDATES")
            requestLocationUpdates()
        }
        return super.onStartCommand(intent, flags, startId)

    }

    private fun startForeground() {
        val notification = createPermanentNotification(applicationContext)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            startForeground(
                NOTIFICATION_PERMANENT_ID,
                notification,
                ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
            )
        } else {
            startForeground(NOTIFICATION_PERMANENT_ID, notification)
        }
        isRunning = true
    }

    private fun notifyForeground() {
        val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        notificationManager.notify(
            NOTIFICATION_PERMANENT_ID,
            createPermanentNotification(applicationContext)
        )
    }

    override fun onDestroy() {
        isRunning = false
        cancelLocationUpdates()
        getGoogleServiceJob?.cancel()
        getGoogleServiceJob = null

        super.onDestroy()
    }

    override fun onCreate() {
        LogEx.logDebug(TAG, "onCreate isRunning=$isRunning")
        if (!isRunning) {
            isRunning = true
            startForeground()
            Timer().start()
        }
        super.onCreate()
    }

    override fun onStartJob(params: JobParameters?): Boolean {
        return true
    }

    override fun onStopJob(params: JobParameters?): Boolean {
        return false
    }

    val millisInFuture = if (BuildConfig.DEBUG) 5000L else 30000L

    private inner class Timer() : CountDownTimer(millisInFuture, 1000) {
        override fun onTick(millisUntilFinished: Long) {

        }

        override fun onFinish() {
            notifyForeground()
            Timer().start()
        }

    }

    private var fusedLocationClient: FusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(MyApplication.appContext)


    /**
     * 请求google service地理位置跟新
     */
    @SuppressLint("MissingPermission")
    fun requestLocationUpdates() {

        // 创建LocationRequest对象，并设置参数
        val locationRequest: LocationRequest = LocationRequest.create()
        locationRequest.setInterval(10000) // 设置更新间隔为10秒
        locationRequest.setFastestInterval(5000) // 设置最快更新间隔为5秒
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) // 设置位置请求的优先级

        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                for (location in locationResult.locations) {
                    // 在这里获取最新的经纬度
                    val latitude = location.latitude
                    val longitude = location.longitude
                }
            }
        }

        locationCallback?.let {
            // 请求位置更新
            fusedLocationClient.requestLocationUpdates(locationRequest, it, Looper.getMainLooper())
        }
        getGoogleServiceLocation()
    }


    /**
     * 取消google service地理位置更新
     */
    private fun cancelLocationUpdates() {
        locationCallback?.let {
            fusedLocationClient.removeLocationUpdates(it)
        }
    }

    private var getGoogleServiceJob: Job? = null

    @SuppressLint("MissingPermission")
    fun getGoogleServiceLocation() {
        if (getGoogleServiceJob == null) {
            getGoogleServiceJob = MainScope().launch(Dispatchers.IO) {
                while (isActive) {
                    fusedLocationClient.lastLocation
                        .addOnSuccessListener { location: Location? ->
                            if (location != null) {
                                val latLng = LatLng(location.latitude, location.longitude)
                                googleLocation = latLng
                                LogEx.logDebug(TAG, "getGoogleServiceLocation latLng=$latLng")
                                if (BuildConfig.DEBUG) {
//                                    MyApplication.appContext.toast("googleLocation=$googleLocation")
                                }
                                oneShotLocationCallBack?.invoke()
                                oneShotLocationCallBack = null

                            }
                        }.addOnFailureListener { e ->
                            LogEx.logDebug(TAG, "e=$e")
                        }

                    delay(getGoogleServiceLocationDelay * 1000L)
                }
            }
        }
    }

}

