package com.tt.honeyDue

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import com.tt.honeyDue.data.DataManager
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d(TAG, "New FCM token: $token")

        // Store token locally for registration with backend
        getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
            .edit()
            .putString(KEY_FCM_TOKEN, token)
            .apply()

        // Send token to backend API if user is logged in
        // Note: In a real app, you might want to use WorkManager for reliable delivery
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val authToken = com.tt.honeyDue.storage.TokenStorage.getToken()
                if (authToken != null) {
                    val notificationApi = com.tt.honeyDue.network.NotificationApi()
                    val deviceId = android.provider.Settings.Secure.getString(
                        applicationContext.contentResolver,
                        android.provider.Settings.Secure.ANDROID_ID
                    )
                    val request = com.tt.honeyDue.models.DeviceRegistrationRequest(
                        deviceId = deviceId,
                        registrationId = token,
                        platform = "android",
                        name = android.os.Build.MODEL
                    )

                    when (val result = notificationApi.registerDevice(authToken, request)) {
                        is com.tt.honeyDue.network.ApiResult.Success -> {
                            Log.d(TAG, "Device registered successfully with new token")
                        }
                        is com.tt.honeyDue.network.ApiResult.Error -> {
                            Log.e(TAG, "Failed to register device with new token: ${result.message}")
                        }
                        is com.tt.honeyDue.network.ApiResult.Loading,
                        is com.tt.honeyDue.network.ApiResult.Idle -> {
                            // These states shouldn't occur for direct API calls
                        }
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Error registering device with new token", e)
            }
        }
    }

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)

        Log.d(TAG, "Message received from: ${message.from}")

        // Check if message contains notification payload
        message.notification?.let { notification ->
            Log.d(TAG, "Notification: ${notification.title} - ${notification.body}")
            sendNotification(
                notification.title ?: "honeyDue",
                notification.body ?: "",
                message.data
            )
        }

        // Check if message contains data payload
        if (message.data.isNotEmpty()) {
            Log.d(TAG, "Message data: ${message.data}")

            // If there's no notification payload, create one from data
            if (message.notification == null) {
                val title = message.data["title"] ?: "honeyDue"
                val body = message.data["body"] ?: ""
                sendNotification(title, body, message.data)
            }
        }
    }

    private fun sendNotification(title: String, body: String, data: Map<String, String>) {
        val taskIdStr = data["task_id"]
        val taskId = taskIdStr?.toIntOrNull()
        val buttonTypesStr = data["button_types"]
        val notificationId = taskId ?: NOTIFICATION_ID

        // Create main tap intent
        val mainIntent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
            data.forEach { (key, value) ->
                putExtra(key, value)
            }
            // Add navigation extra if task notification
            if (taskId != null) {
                putExtra(NotificationActionReceiver.EXTRA_NAVIGATE_TO_TASK, taskId)
            }
        }

        val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        } else {
            PendingIntent.FLAG_UPDATE_CURRENT
        }

        val mainPendingIntent = PendingIntent.getActivity(
            this,
            notificationId,
            mainIntent,
            pendingIntentFlags
        )

        val channelId = getString(R.string.default_notification_channel_id)
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setContentIntent(mainPendingIntent)
            .setPriority(NotificationCompat.PRIORITY_HIGH)

        // Add action buttons for premium users with task notifications
        if (taskId != null && isPremiumUser()) {
            addActionButtons(notificationBuilder, taskId, notificationId, buttonTypesStr)
        }

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Create notification channel for Android O and above
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "honeyDue Notifications",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                description = "Notifications for tasks, residences, and warranties"
            }
            notificationManager.createNotificationChannel(channel)
        }

        notificationManager.notify(notificationId, notificationBuilder.build())
    }

    private fun isPremiumUser(): Boolean {
        val subscription = DataManager.subscription.value
        // User is premium if limitations are disabled
        return subscription?.limitationsEnabled == false
    }

    private fun addActionButtons(
        builder: NotificationCompat.Builder,
        taskId: Int,
        notificationId: Int,
        buttonTypesStr: String?
    ) {
        val buttonTypes = buttonTypesStr?.split(",")?.map { it.trim() } ?: emptyList()

        val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        } else {
            PendingIntent.FLAG_UPDATE_CURRENT
        }

        // Add up to 3 action buttons (Android notification limit)
        var actionCount = 0
        val maxActions = 3

        for (buttonType in buttonTypes) {
            if (actionCount >= maxActions) break

            val (action, label) = when (buttonType) {
                "complete" -> NotificationActionReceiver.ACTION_COMPLETE_TASK to "Complete"
                "mark_in_progress" -> NotificationActionReceiver.ACTION_MARK_IN_PROGRESS to "Start"
                "cancel" -> NotificationActionReceiver.ACTION_CANCEL_TASK to "Cancel"
                "uncancel" -> NotificationActionReceiver.ACTION_UNCANCEL_TASK to "Restore"
                else -> continue
            }

            val intent = Intent(this, NotificationActionReceiver::class.java).apply {
                this.action = action
                putExtra(NotificationActionReceiver.EXTRA_TASK_ID, taskId)
                putExtra(NotificationActionReceiver.EXTRA_NOTIFICATION_ID, notificationId)
            }

            val pendingIntent = PendingIntent.getBroadcast(
                this,
                notificationId * 10 + actionCount, // Unique request code per action
                intent,
                pendingIntentFlags
            )

            builder.addAction(0, label, pendingIntent)
            actionCount++
        }
    }

    companion object {
        private const val TAG = "FCMService"
        private const val NOTIFICATION_ID = 0
        private const val PREFS_NAME = "honeydue_prefs"
        private const val KEY_FCM_TOKEN = "fcm_token"

        fun getStoredToken(context: Context): String? {
            return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
                .getString(KEY_FCM_TOKEN, null)
        }
    }
}
