package com.openclaw.alfred.fcm

import android.app.PendingIntent
import android.content.Intent
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.openclaw.alfred.alarm.AlarmActivity
import com.openclaw.alfred.alarm.AlarmManager
import com.openclaw.alfred.notifications.NotificationHelper

/**
 * Firebase Cloud Messaging service for handling push notifications.
 * Used to wake the device when alarms trigger while screen is off.
 */
class AlfredFirebaseMessagingService : FirebaseMessagingService() {
    
    private val TAG = "FCM"
    
    /**
     * Called when a new FCM token is generated.
     * This happens on first install and periodically thereafter.
     */
    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d(TAG, "New FCM token: $token")
        
        // Store token for sending to proxy when connected
        val prefs = getSharedPreferences("alfred_prefs", MODE_PRIVATE)
        prefs.edit()
            .putString("fcm_token", token)
            .putBoolean("fcm_token_needs_sync", true)
            .apply()
        
        Log.d(TAG, "FCM token saved to preferences")
    }
    
    /**
     * Called when a push notification is received while app is in foreground.
     * For background/killed app, the system tray notification is shown automatically.
     */
    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)
        
        Log.d(TAG, "Message received from: ${message.from}")
        Log.d(TAG, "Message data: ${message.data}")
        
        // Extract notification data
        val messageType = message.data["type"]
        val notificationType = message.data["notificationType"] ?: "alert"
        val title = message.data["title"] ?: "AI Assistant"
        val messageText = message.data["message"] ?: ""
        val alarmId = message.data["alarmId"]
        
        Log.d(TAG, "Notification: type=$notificationType title=$title message=$messageText")
        
        // Handle alarm dismissal broadcast
        if (messageType == "alarm_dismiss" && alarmId != null) {
            Log.d(TAG, "Received alarm dismissal via FCM: $alarmId")
            val alarmManager = AlarmManager.getInstance(this)
            alarmManager.dismissAlarm(alarmId)
            return
        }
        
        if (messageText.isNotEmpty()) {
            if (notificationType == "alarm") {
                Log.d(TAG, "FCM Alarm received - launching full-screen alarm activity")
                
                // Generate alarm ID
                val timestamp = System.currentTimeMillis()
                val generatedAlarmId = alarmId ?: "fcm-alarm-$timestamp"
                
                // Start alarm sound/vibration
                val alarmManager = AlarmManager.getInstance(this)
                alarmManager.startAlarm(
                    alarmId = generatedAlarmId,
                    title = title,
                    message = messageText,
                    enableSound = true,
                    enableVibrate = true
                )
                
                // Create intent for full-screen alarm activity
                val alarmIntent = Intent(this, AlarmActivity::class.java).apply {
                    putExtra(AlarmActivity.EXTRA_ALARM_ID, generatedAlarmId)
                    putExtra(AlarmActivity.EXTRA_TITLE, title)
                    putExtra(AlarmActivity.EXTRA_MESSAGE, messageText)
                    putExtra(AlarmActivity.EXTRA_TIMESTAMP, timestamp)
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK or 
                           Intent.FLAG_ACTIVITY_CLEAR_TOP or
                           Intent.FLAG_ACTIVITY_SINGLE_TOP
                }
                
                // Don't launch activity directly from background service (Android 13 restriction)
                // Instead, rely on the notification's full-screen intent to show the alarm
                
                // Create notification with full-screen intent for lock screen
                val fullScreenPendingIntent = PendingIntent.getActivity(
                    this,
                    generatedAlarmId.hashCode(),
                    alarmIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                )
                
                // Create dismiss action
                val dismissIntent = Intent("com.openclaw.alfred.DISMISS_ALARM").apply {
                    putExtra("alarm_id", generatedAlarmId)
                    setPackage(packageName)
                }
                
                val dismissPendingIntent = PendingIntent.getBroadcast(
                    this,
                    (generatedAlarmId.hashCode() + 1),
                    dismissIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                )
                
                // Show high-priority notification with full-screen intent
                NotificationHelper.showAlarmNotification(
                    context = this,
                    alarmId = generatedAlarmId,
                    title = title,
                    message = messageText,
                    fullScreenIntent = fullScreenPendingIntent,
                    dismissAction = dismissPendingIntent
                )
                
            } else {
                // For other notifications, show them directly
                NotificationHelper.showNotification(
                    context = this,
                    title = title,
                    message = messageText,
                    autoCancel = true
                )
            }
        }
    }
    
    /**
     * Called when message couldn't be delivered within TTL.
     */
    override fun onDeletedMessages() {
        super.onDeletedMessages()
        Log.w(TAG, "Messages deleted (exceeded TTL)")
    }
    
    /**
     * Called when FCM server sends an error.
     */
    override fun onMessageSent(msgId: String) {
        super.onMessageSent(msgId)
        Log.d(TAG, "Message sent: $msgId")
    }
    
    /**
     * Called when sending a message failed.
     */
    override fun onSendError(msgId: String, exception: Exception) {
        super.onSendError(msgId, exception)
        Log.e(TAG, "Send error for message $msgId", exception)
    }
}
