package com.dvox.gifunavi


import android.location.Location
import android.Manifest
import android.annotation.TargetApi
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
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.location.Priority
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import android.app.Notification


data class GpsData(
    val id: Int,
    val teamName: String,
    val eventCode: String,
    val lat: Double,
    val lon: Double,
    val isCheckin: Int,
    val createdAt: Long
)

class GpsDatabaseHelper(private val context: Context) {
    fun insertGps(gpsData: GpsData) {
        Log.d("LocationService", "Android: insertGps.")

        // ここにデータベースへの挿入処理を実装する
    }

    companion object {
        fun getInstance(context: Context): GpsDatabaseHelper {
            Log.d("LocationService", "Android: GpsDatabaseHelper.")
            return GpsDatabaseHelper(context)
        }
    }
}

class LocationService : Service() {
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var gpsDatabaseHelper: GpsDatabaseHelper

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        Log.d("LocationService", "Android: onCreate.")

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
        gpsDatabaseHelper = GpsDatabaseHelper.getInstance(applicationContext)

        // 位置情報の権限チェックとGPS有効化の確認を行う
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE) == PackageManager.PERMISSION_GRANTED) {
            //ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            Log.d("LocationService", "Android: onCreate : 位置情報の権限チェックとGPS有効化の確認")

            val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
            if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
                    .setMinUpdateIntervalMillis(5000)
                    .build()
/*
val locationRequest = LocationRequest.create().apply {
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    interval = 10000
    fastestInterval = 5000
}
 */

                fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)

                // フォアグラウンドサービスの設定
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val channel = NotificationChannel(CHANNEL_ID, "Location", NotificationManager.IMPORTANCE_DEFAULT)
                    val notificationManager = getSystemService(NotificationManager::class.java)
                    notificationManager?.createNotificationChannel(channel)
                }
                val notification = NotificationCompat.Builder(this, CHANNEL_ID)
                    .setContentTitle("Tracking location...")
                    .setContentText("Location: null")
                    .setSmallIcon(android.R.drawable.ic_menu_mylocation)
                    .setOngoing(true)
                    .build()

                startForeground(NOTIFICATION_ID, notification)
            } else {
                Log.d("LocationService", "GPS is disabled.")
                // GPSが無効の場合の処理を追加する（例: ユーザーにGPSを有効にするように促すなど）
                stopSelf() // サービスを停止する
            }
        } else {
            Log.d("LocationService", "Location permission or Foreground service location permission is not granted.")
            // 位置情報の権限またはフォアグラウンドサービスの位置情報の権限が許可されていない場合の処理を追加する
            stopSelf() // サービスを停止する
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    @TargetApi(Build.VERSION_CODES.N)
    override fun onDestroy() {
        super.onDestroy()
        Log.d("LocationService", "Android: onDestroy.")
        fusedLocationClient.removeLocationUpdates(locationCallback)
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()
    }

    companion object {
        private const val NOTIFICATION_ID = 1
        private const val CHANNEL_ID = "location_service_channel"
    }

    private fun createNotification(): Notification {
        Log.d("LocationService", "Android: createNotification Notification.")
        val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Location Service")
            .setContentText("Running...")
            .setSmallIcon(android.R.drawable.ic_menu_mylocation)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelName = "Location Service Channel"
            val channelDescription = "Channel for Location Service"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, channelName, importance).apply {
                description = channelDescription
            }
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }

        return notificationBuilder.build()
    }

    private fun createNotificationChannel() {
        Log.d("LocationService", "Android: createNotificationChannel.")

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "Location Service Channel",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }

    private var lastLocation: Location? = null

    private val locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            val currentLocation = locationResult.lastLocation
            if (currentLocation != null) {
                val accuracy = currentLocation.accuracy
                if (accuracy <= 30) {
                    var lastLocation = lastLocation
                    if (lastLocation == null || currentLocation.distanceTo(lastLocation) >= 10) {
                        val lat = currentLocation.latitude
                        val lon = currentLocation.longitude
                        val currentTime = System.currentTimeMillis()

                        // GPSデータをデバッグ用に表示
                        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                        val formattedTime = sdf.format(Date(currentTime))
                        //Log.d("LocationService", "Android: {$formattedTime}")


                        // GPSデータをデータベースに保存
                        GlobalScope.launch(Dispatchers.IO) {
                            addGPStoDB(lat, lon, currentTime)
                        }

                        lastLocation = currentLocation
                    }
                } else {
                    Log.d("LocationService", "Android: GPS accuracy is above 30m. Skipping data saving.")
                }
            } else {
                Log.d("LocationService", "Android: No GPS signal received.")
            }
        }
    }


    /*
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            Log.d("LocationService", "Android: onStartCommand.")

            // Foregroundサービスを開始
            startForeground(NOTIFICATION_ID, createNotification())

            return START_STICKY
        }
    */

    private suspend fun addGPStoDB(lat: Double, lng: Double, timestamp: Long, isCheckin: Int = 0) {
        try {
            val context = applicationContext
            val preferences = context.getSharedPreferences("RogPreferences", Context.MODE_PRIVATE)
            val teamName = preferences.getString("team_name", "") ?: ""
            val eventCode = preferences.getString("event_code", "") ?: ""

            if (teamName.isNotEmpty() && eventCode.isNotEmpty()) {
                val gpsData = GpsData(
                    id = 0,
                    teamName = teamName,
                    eventCode = eventCode,
                    lat = lat,
                    lon = lng,
                    isCheckin = isCheckin,
                    createdAt = timestamp
                )

                gpsDatabaseHelper.insertGps(gpsData)
                Log.d("LocationService", "Android: addGPStoDB.")
            }
        } catch (e: Exception) {
            Log.e("LocationService", "Error adding GPS data to DB", e)
            // エラーメッセージをユーザーに表示するなどの処理を追加
        }
    }
}

