package com.jordanbot.autoride.service

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.tasks.Tasks

import android.app.Notification
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import android.util.Log
import com.jordanbot.autoride.api.ApiClient
import com.jordanbot.autoride.api.RideLogRequest
import com.jordanbot.autoride.filter.FilterEngine
import com.jordanbot.autoride.engine.RideDataMerger
import com.jordanbot.autoride.parser.*
import com.jordanbot.autoride.utils.DeviceUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch

class RideNotificationListener : NotificationListenerService() {

    private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override fun onCreate() {
        super.onCreate()
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    }

    private val parsers = listOf(
        UberParser(),
        CareemParser(),
        JeenyParser(),
        PetraRideParser(),
        TaxiFParser()
    )
    
    companion object {
        var pendingAcceptPackage: String? = null
        var lastRequestTime: Long = 0
    }

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        var packageName = sbn.packageName
        Log.d("JordanBot", "Received notification from: $packageName")

        // TEMPORARY: Allow Shell notifications for testing
        if (packageName == "com.android.shell") {
            Log.d("JordanBot", "Testing mode: Treating Shell notification as Uber")
            packageName = "com.ubercab.driver"
        }
        
        val parser = parsers.find { it.packageName == packageName }
        if (parser == null) {
            Log.d("JordanBot", "No parser found for package: $packageName")
            return
        }

        val notification = sbn.notification
        val extras = notification.extras
        val title = extras.getString(Notification.EXTRA_TITLE) ?: ""
        val text = extras.getCharSequence(Notification.EXTRA_TEXT)?.toString() ?: ""

        Log.d("JordanBot", "Notification Content: $title | $text")

        val rideRequest = parser.parse(title, text)
        if (rideRequest != null) {
            // Forward to Merger instead of processing here
            RideDataMerger.updateFromNotification(rideRequest)
        } else {
            Log.d("JordanBot", "Parser failed to extract ride info from: $title | $text")
        }
    }

    private fun sendLogToBackend(ride: com.jordanbot.autoride.model.RideRequest, isAccepted: Boolean, rawText: String) {
        serviceScope.launch {
            var lat: Double? = null
            var lng: Double? = null

            // Try to get current location
            if (ContextCompat.checkSelfPermission(this@RideNotificationListener, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                try {
                    val location = Tasks.await(fusedLocationClient.lastLocation)
                    if (location != null) {
                        lat = location.latitude
                        lng = location.longitude
                        Log.d("JordanBot", "📍 Location attached to ride: $lat, $lng")
                    }
                } catch (e: Exception) {
                    Log.e("JordanBot", "Failed to get location for ride log", e)
                }
            }

            val logRequest = RideLogRequest(
                platform = ride.appPackage,
                price = ride.priceJod ?: 0.0,
                pickupDistance = ride.distanceKm?.toString() ?: "Unknown",
                dropoffDistance = "Unknown",
                timeToPickup = ride.minutesAway?.toString() ?: "Unknown",
                pickupAddress = ride.pickupAddress ?: "Unknown",
                dropoffAddress = ride.dropoffAddress ?: "Unknown",
                isAccepted = isAccepted,
                rawText = rawText,
                fingerprint = DeviceUtils.getDeviceFingerprint(this@RideNotificationListener),
                latitude = lat,
                longitude = lng
            )
            try {
                val response = ApiClient.service.logRide(logRequest)
                if (response.success) {
                    Log.d("JordanBot", "✅ Ride log sent to server")
                }
            } catch (e: retrofit2.HttpException) {
                val errorBody = e.response()?.errorBody()?.string()
                Log.e("JordanBot", "❌ Failed to send ride log: HTTP ${e.code()} - Body: $errorBody", e)
            } catch (e: Exception) {
                Log.e("JordanBot", "❌ Failed to send ride log", e)
            }
        }
    }

    override fun onListenerConnected() {
        super.onListenerConnected()
        Log.d("JordanBot", "Notification Listener Connected")
    }
}
