package com.Intaleq.intaleq

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.os.Looper
import android.util.Log
import android.view.View
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
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 kotlin.math.*

class RideTrackingService : Service() {

    companion object {
        private const val TAG = "RideTrackingService"

        const val CHANNEL_ID = "TRIP_LIVE_ACTIVITY_CHANNEL"
        const val NOTIFICATION_ID = 1001

        fun startOrUpdate(
                context: Context,
                driverName: String,
                driverPhone: String,
                carDetails: String,
                driverLat: Double,
                driverLng: Double,
                passengerLat: Double,
                passengerLng: Double,
                destLat: Double,
                destLng: Double,
                rideState: String,
                estimatedTime: Int,
                totalDistance: Double
        ) {
            val intent =
                    Intent(context, RideTrackingService::class.java).apply {
                        putExtra("driverName", driverName)
                        putExtra("driverPhone", driverPhone)
                        putExtra("carDetails", carDetails)

                        putExtra("driverLat", driverLat)
                        putExtra("driverLng", driverLng)
                        putExtra("passengerLat", passengerLat)
                        putExtra("passengerLng", passengerLng)
                        putExtra("destLat", destLat)
                        putExtra("destLng", destLng)

                        putExtra("rideState", rideState)
                        putExtra("estimatedTime", estimatedTime)
                        putExtra("totalDistance", totalDistance)
                    }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
        }

        fun stop(context: Context) {
            val intent = Intent(context, RideTrackingService::class.java)
            context.stopService(intent)
        }
    }

    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var locationCallback: LocationCallback
    private lateinit var notificationManager: NotificationManager

    private var driverLatitude = 0.0
    private var driverLongitude = 0.0
    private var passengerLatitude = 0.0
    private var passengerLongitude = 0.0
    private var destinationLatitude = 0.0
    private var destinationLongitude = 0.0

    private var rideState: String = "waiting"
    private var driverName: String = "السائق"
    private var driverPhone: String = ""
    private var carDetails: String = ""
    private var estimatedTimeMinutes: Int = 0
    private var totalDistanceMeters: Double = 0.0
    private var distanceCoveredMeters: Double = 0.0

    private var initialDriverDistanceToPassenger: Double = -1.0

    override fun onCreate() {
        super.onCreate()

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
        notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        setupLocationCallback()
        createNotificationChannel()

        Log.d(TAG, "Service Created")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "Service Started")

        intent?.let {
            driverName = it.getStringExtra("driverName") ?: "السائق"
            driverPhone = it.getStringExtra("driverPhone") ?: ""
            carDetails = it.getStringExtra("carDetails") ?: ""

            driverLatitude = it.getDoubleExtra("driverLat", 0.0)
            driverLongitude = it.getDoubleExtra("driverLng", 0.0)
            passengerLatitude = it.getDoubleExtra("passengerLat", 0.0)
            passengerLongitude = it.getDoubleExtra("passengerLng", 0.0)
            destinationLatitude = it.getDoubleExtra("destLat", 0.0)
            destinationLongitude = it.getDoubleExtra("destLng", 0.0)

            rideState = it.getStringExtra("rideState") ?: "waiting"
            estimatedTimeMinutes = it.getIntExtra("estimatedTime", 5)
            totalDistanceMeters = it.getDoubleExtra("totalDistance", 0.0)
        }

        if (rideState == "waiting" && initialDriverDistanceToPassenger < 0) {
            val currentDist =
                    calculateDistance(
                            passengerLatitude,
                            passengerLongitude,
                            driverLatitude,
                            driverLongitude
                    )
            initialDriverDistanceToPassenger =
                    if (totalDistanceMeters > currentDist) totalDistanceMeters else currentDist
        }

        startForeground(NOTIFICATION_ID, createNotification())
        startLocationUpdates()

        return START_STICKY
    }

    private fun setupLocationCallback() {
        locationCallback =
                object : LocationCallback() {
                    override fun onLocationResult(locationResult: LocationResult) {
                        for (location in locationResult.locations) {
                            passengerLatitude = location.latitude
                            passengerLongitude = location.longitude

                            if (rideState == "inProgress" && totalDistanceMeters > 0) {
                                val remainingToDest =
                                        calculateDistance(
                                                passengerLatitude,
                                                passengerLongitude,
                                                destinationLatitude,
                                                destinationLongitude
                                        )
                                distanceCoveredMeters =
                                        (totalDistanceMeters - remainingToDest).coerceAtLeast(0.0)
                            }

                            updateNotification()
                        }
                    }
                }
    }

    private fun startLocationUpdates() {
        val locationRequest =
                LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000L)
                        .setMinUpdateIntervalMillis(2000L)
                        .build()

        try {
            fusedLocationClient.requestLocationUpdates(
                    locationRequest,
                    locationCallback,
                    Looper.getMainLooper()
            )
        } catch (e: SecurityException) {
            Log.e(TAG, "Location permission denied: ${e.message}")
        }
    }

    private fun createNotification(): Notification {
        val contentText = buildContentText()

        // 1. جلب التصميم المخصص
        val layoutId = resources.getIdentifier("notification_ride_live", "layout", packageName)

        // إذا لم يجد الملف، سيطبع خطأ أحمر في اللوج
        if (layoutId == 0) {
            Log.e(TAG, "❌ خطأ فادح: ملف notification_ride_live.xml غير موجود!")
        }

        val remoteViews = RemoteViews(packageName, layoutId)

        // 2. تعبئة النصوص
        val subtitleId = resources.getIdentifier("tv_subtitle", "id", packageName)
        val etaId = resources.getIdentifier("tv_eta", "id", packageName)
        val titleId = resources.getIdentifier("tv_title", "id", packageName)

        if (subtitleId != 0) remoteViews.setTextViewText(subtitleId, "$driverName • $carDetails")
        if (etaId != 0) remoteViews.setTextViewText(etaId, contentText)
        if (titleId != 0)
                remoteViews.setTextViewText(
                        titleId,
                        if (rideState == "waiting") "السائق في الطريق إليك"
                        else "رحلة Intaleq جارية"
                )

        // 3. حساب التقدم (موقع السيارة على الشارع)
        var progressIndex = 0
        if (rideState == "inProgress" && totalDistanceMeters > 0) {
            val percent = (distanceCoveredMeters / totalDistanceMeters).coerceIn(0.0, 1.0)
            progressIndex = (percent * 9).toInt()
        } else if (rideState == "waiting") {
            val remainingToPassenger =
                    calculateDistance(
                            passengerLatitude,
                            passengerLongitude,
                            driverLatitude,
                            driverLongitude
                    )
            val total =
                    if (initialDriverDistanceToPassenger > 0) initialDriverDistanceToPassenger
                    else remainingToPassenger.coerceAtLeast(1.0)
            val percent = 1.0 - (remainingToPassenger / total).coerceIn(0.0, 1.0)
            progressIndex = (percent * 9).toInt()
        }

        // 4. إظهار السيارة في الموضع الصحيح وإخفائها من الباقي
        for (i in 0..9) {
            val resId = resources.getIdentifier("car_slot_$i", "id", packageName)
            if (resId != 0) {
                remoteViews.setViewVisibility(
                        resId,
                        if (i == progressIndex) View.VISIBLE else View.INVISIBLE
                )
            }
        }

        val intent = Intent(this, MainActivity::class.java)
        val pendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        intent,
                        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                )

        // 5. بناء الإشعار (بدون استخدام setProgress نهائياً لكي لا يظهر الخط الأزرق)
        val builder =
                NotificationCompat.Builder(this, CHANNEL_ID)
                        .setSmallIcon(android.R.drawable.ic_dialog_map) // أيقونة التطبيق الصغيرة
                        .setStyle(
                                NotificationCompat.DecoratedCustomViewStyle()
                        ) // إجباري للتصميم المخصص
                        .setCustomContentView(remoteViews) // التصميم عند طي الإشعار
                        .setCustomBigContentView(remoteViews) // التصميم عند سحب الإشعار للأسفل
                        .setContentIntent(pendingIntent)
                        .setOngoing(true)
                        .setPriority(NotificationCompat.PRIORITY_MAX)
                        .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)

        return builder.build()
    }

    private fun buildContentText(): String {
        return when (rideState) {
            "waiting" -> {
                val distanceToPassenger =
                        calculateDistance(
                                passengerLatitude,
                                passengerLongitude,
                                driverLatitude,
                                driverLongitude
                        )

                val etaMinutes =
                        if (distanceToPassenger > 0) {
                            (distanceToPassenger / 250.0).toInt().coerceAtLeast(1)
                        } else {
                            estimatedTimeMinutes
                        }

                "وصول خلال $etaMinutes د • ${String.format("%.1f", distanceToPassenger / 1000)} كم"
            }
            "inProgress" -> {
                if (totalDistanceMeters > 0) {
                    val remaining = (totalDistanceMeters - distanceCoveredMeters).coerceAtLeast(0.0)
                    val progressPercent =
                            ((distanceCoveredMeters / totalDistanceMeters) * 100)
                                    .toInt()
                                    .coerceIn(0, 100)

                    val etaMinutes =
                            if (estimatedTimeMinutes > 0) {
                                ((remaining / totalDistanceMeters) * estimatedTimeMinutes)
                                        .toInt()
                                        .coerceAtLeast(1)
                            } else {
                                5
                            }

                    "المتبقي: ${String.format("%.1f", remaining / 1000)} كم • ~$etaMinutes د"
                } else {
                    "الرحلة قيد التنفيذ..."
                }
            }
            else -> "جاري تحديث موقع الرحلة..."
        }
    }

    private fun updateNotification() {
        val notification = createNotification()
        notificationManager.notify(NOTIFICATION_ID, notification)
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel =
                    NotificationChannel(
                                    CHANNEL_ID,
                                    "تتبع الرحلة",
                                    NotificationManager.IMPORTANCE_HIGH
                            )
                            .apply {
                                description = "إخطارات حية لتقدم الرحلة"
                                lockscreenVisibility = Notification.VISIBILITY_PUBLIC
                                setSound(null, null)
                            }

            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun calculateDistance(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Double {
        val r = 6371000.0
        val dLat = Math.toRadians(lat2 - lat1)
        val dLng = Math.toRadians(lng2 - lng1)

        val a =
                sin(dLat / 2) * sin(dLat / 2) +
                        cos(Math.toRadians(lat1)) *
                                cos(Math.toRadians(lat2)) *
                                sin(dLng / 2) *
                                sin(dLng / 2)

        val c = 2 * atan2(sqrt(a), sqrt(1 - a))
        return r * c
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            fusedLocationClient.removeLocationUpdates(locationCallback)
        } catch (e: Exception) {
            Log.e(TAG, "Error removing location updates: ${e.message}")
        }
        Log.d(TAG, "Service Destroyed")
    }

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