package com.anypreta.bountyboard.data.push

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.anypreta.bountyboard.MainActivity
import com.anypreta.bountyboard.R

/**
 * Owns the notification channels and posts system notifications for alerts and
 * messages, each deep-linking back into the app.
 */
object PushNotifier {

    const val CHANNEL_ALERTS = "alerts"
    const val CHANNEL_MESSAGES = "messages"
    const val CHANNEL_SERVICE = "live"
    const val SERVICE_NOTIF_ID = 1001
    const val EXTRA_ROUTE = "bb_route"

    fun ensureChannels(context: Context) {
        val mgr = context.getSystemService(NotificationManager::class.java) ?: return
        mgr.createNotificationChannel(
            NotificationChannel(CHANNEL_ALERTS, "Alerts", NotificationManager.IMPORTANCE_HIGH).apply {
                description = "Claim requests, approvals, reviews, mentions and sync alerts"
            },
        )
        mgr.createNotificationChannel(
            NotificationChannel(CHANNEL_MESSAGES, "Messages", NotificationManager.IMPORTANCE_HIGH).apply {
                description = "New direct, group and project messages"
            },
        )
        mgr.createNotificationChannel(
            NotificationChannel(CHANNEL_SERVICE, "Live updates", NotificationManager.IMPORTANCE_LOW).apply {
                description = "Keeps a connection open so alerts and messages arrive instantly"
                setShowBadge(false)
            },
        )
    }

    /** The ongoing notification shown while the live-updates foreground service runs. */
    fun serviceNotification(context: Context): android.app.Notification =
        NotificationCompat.Builder(context, CHANNEL_SERVICE)
            .setSmallIcon(R.drawable.ic_stat_diamond)
            .setContentTitle("Bounty Board")
            .setContentText("Listening for alerts and messages")
            .setOngoing(true)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setContentIntent(deepLinkIntent(context, null, 0))
            .build()

    private fun deepLinkIntent(context: Context, route: String?, requestCode: Int): PendingIntent {
        val intent = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
            if (route != null) putExtra(EXTRA_ROUTE, route)
        }
        return PendingIntent.getActivity(
            context,
            requestCode,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )
    }

    fun notifyAlert(context: Context, id: Int, title: String, body: String, route: String?) {
        post(context, CHANNEL_ALERTS, id, title, body, route)
    }

    fun notifyMessage(context: Context, id: Int, title: String, body: String, route: String?) {
        post(context, CHANNEL_MESSAGES, id, title, body, route)
    }

    private fun post(context: Context, channel: String, id: Int, title: String, body: String, route: String?) {
        val nm = NotificationManagerCompat.from(context)
        if (!nm.areNotificationsEnabled()) return
        val n = NotificationCompat.Builder(context, channel)
            .setSmallIcon(R.drawable.ic_stat_diamond)
            .setContentTitle(title.ifBlank { "Bounty Board" })
            .setContentText(body)
            .setStyle(NotificationCompat.BigTextStyle().bigText(body))
            .setAutoCancel(true)
            .setContentIntent(deepLinkIntent(context, route, id))
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build()
        try {
            nm.notify(id, n)
        } catch (_: SecurityException) {
            // POST_NOTIFICATIONS not granted — silently skip.
        }
    }

    /** Map a server-relative notification link to an in-app nav route. */
    fun routeForServerLink(link: String?): String? {
        val clean = link?.trim()?.trim('/') ?: return null
        return when {
            clean.startsWith("tasks/") -> "task/${clean.removePrefix("tasks/")}"
            clean.startsWith("conversations/") -> "conversation/${clean.removePrefix("conversations/")}"
            clean == "board" -> "board"
            clean.isEmpty() -> "notifications"
            else -> "notifications"
        }
    }
}
