/*
 * Hermes Node Android
 * Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package net.nexlab.hermesnodeandroid.capabilities

import android.app.NotificationManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.provider.Settings
import net.nexlab.hermesnodeandroid.CapabilityResult
import net.nexlab.hermesnodeandroid.HermesNotificationListenerService
import net.nexlab.hermesnodeandroid.NotificationSessionStore
import org.json.JSONArray
import org.json.JSONObject

class AndroidNotificationAccess(private val context: Context) {
    fun capabilityInfo(): JSONObject = JSONObject()
        .put("available", true)
        .put("listener_enabled", isListenerEnabled())
        .put("actions", JSONArray(listOf(
            "get_notification_status",
            "list_notifications",
            "open_notification",
            "dismiss_notification",
        )))

    fun handle(action: String?, params: JSONObject): CapabilityResult = when (action) {
        "get_notification_status" -> getStatus()
        "list_notifications" -> listNotifications(params)
        "open_notification" -> openNotification(params)
        "dismiss_notification" -> dismissNotification(params)
        else -> CapabilityResult.unsupported("Unknown notification_access action: $action")
    }

    private fun getStatus(): CapabilityResult = CapabilityResult.ok(
        "available" to true,
        "listener_enabled" to isListenerEnabled(),
        "settings_intent" to Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS,
    )

    private fun listNotifications(params: JSONObject): CapabilityResult {
        if (!isListenerEnabled()) {
            return CapabilityResult.unsupported("Notification listener access is not enabled; open Android notification access settings and enable Hermes Node")
        }
        val limit = params.optInt("limit", 50).coerceIn(1, 200)
        val snapshot = NotificationSessionStore.loadSnapshot(context) ?: JSONArray()
        val trimmed = JSONArray()
        for (i in 0 until minOf(limit, snapshot.length())) trimmed.put(snapshot.getJSONObject(i))
        return CapabilityResult.ok(
            "count" to trimmed.length(),
            "notifications" to trimmed,
        )
    }

    private fun openNotification(params: JSONObject): CapabilityResult {
        val key = params.optString("key")
        if (key.isBlank()) return CapabilityResult.unsupported("open_notification requires notification key")
        val snapshot = NotificationSessionStore.loadSnapshot(context) ?: JSONArray()
        val match = findByKey(snapshot, key) ?: return CapabilityResult.unsupported("Notification not found: $key")
        val packageName = match.optString("package_name")
        val launch = context.packageManager.getLaunchIntentForPackage(packageName)
            ?: return CapabilityResult.unsupported("No launch intent for notification package: $packageName")
        launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(launch)
        return CapabilityResult.ok("opened_package" to packageName, "key" to key)
    }

    private fun dismissNotification(params: JSONObject): CapabilityResult {
        if (!isListenerEnabled()) {
            return CapabilityResult.unsupported("Notification listener access is not enabled")
        }
        val key = params.optString("key")
        if (key.isBlank()) return CapabilityResult.unsupported("dismiss_notification requires notification key")
        return try {
            val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.cancel(key.hashCode())
            CapabilityResult.ok("dismiss_requested" to true, "key" to key)
        } catch (e: Exception) {
            CapabilityResult.unsupported("dismiss_notification failed: ${e.message}")
        }
    }

    private fun isListenerEnabled(): Boolean {
        val enabled = Settings.Secure.getString(context.contentResolver, "enabled_notification_listeners").orEmpty()
        val me = ComponentName(context, HermesNotificationListenerService::class.java).flattenToString()
        return enabled.split(':').any { it == me }
    }

    private fun findByKey(snapshot: JSONArray, key: String): JSONObject? {
        for (i in 0 until snapshot.length()) {
            val obj = snapshot.optJSONObject(i) ?: continue
            if (obj.optString("key") == key) return obj
        }
        return null
    }
}
