package app.closer.core.notifications

import app.closer.domain.repository.AuthRepository
import app.closer.domain.repository.UserRepository
import app.closer.notifications.NotificationChannelSetup
import app.closer.notifications.PartnerNotificationManager
import app.closer.notifications.PartnerNotificationPayload
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class AppMessagingService : FirebaseMessagingService() {

    @Inject lateinit var authRepository: AuthRepository
    @Inject lateinit var userRepository: UserRepository
    @Inject lateinit var partnerNotificationManager: PartnerNotificationManager
    @Inject lateinit var activeThreadMonitor: app.closer.notifications.ActiveThreadMonitor
    @Inject lateinit var messageBubbleController: app.closer.notifications.MessageBubbleController

    private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

    override fun onCreate() {
        super.onCreate()
        NotificationChannelSetup.createChannels(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        serviceScope.cancel()
    }

    override fun onNewToken(token: String) {
        val uid = authRepository.currentUserId ?: return
        serviceScope.launch {
            runCatching {
                userRepository.storeFcmToken(uid, token)
                userRepository.storeTokenMetadata(
                    uid, token, TokenRegistrar.DeviceMetadata(
                        platform = "android",
                        osVersion = android.os.Build.VERSION.RELEASE ?: "unknown",
                        appVersion = app.closer.BuildConfig.VERSION_NAME,
                        sdkVersion = android.os.Build.VERSION.SDK_INT,
                        timestamp = System.currentTimeMillis()
                    )
                )
            }
        }
    }

    override fun onMessageReceived(message: RemoteMessage) {
        val coupleId = message.data["couple_id"] ?: return
        val type = message.data["type"] ?: return

        // This callback fires only while the app is in the FOREGROUND (backgrounded delivery is
        // shown by the OS from the FCM notification block). For a chat message, surface the
        // draggable in-app bubble — unless the user is already reading that exact thread.
        if (type == "chat_message") {
            val conversationId = message.data["conversation_id"]
            if (conversationId != null && conversationId != activeThreadMonitor.activeConversationId) {
                messageBubbleController.show(coupleId, conversationId, message.data["sender_avatar_url"])
            }
            return
        }

        serviceScope.launch {
            runCatching {
                partnerNotificationManager.handleRemote(
                    type = type,
                    coupleId = coupleId,
                    payload = PartnerNotificationPayload(
                        questionId = message.data["question_id"],
                        conversationId = message.data["conversation_id"],
                        gameSessionId = message.data["game_session_id"],
                        capsuleId = message.data["capsule_id"],
                        challengeId = message.data["challenge_id"],
                        avatarUrl = message.data["sender_avatar_url"]
                    )
                )
            }
        }
    }
}
