/*
 * Copyright (c) 2026 Meshtastic LLC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package org.meshtastic.core.service

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.core.app.RemoteInput
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.meshtastic.core.di.CoroutineDispatchers
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.RadioController
import org.meshtastic.core.repository.MeshServiceNotifications

/**
 * A [BroadcastReceiver] that handles inline replies from notifications.
 *
 * This receiver is triggered when a user replies to a message directly from a notification. It extracts the reply text
 * and the contact key from the intent, sends the message using the [ServiceRepository], and then cancels the original
 * notification.
 */
class ReplyReceiver :
    BroadcastReceiver(),
    KoinComponent {
    private val radioController: RadioController by inject()

    private val meshServiceNotifications: MeshServiceNotifications by inject()

    private val dispatchers: CoroutineDispatchers by inject()

    private val scope by lazy { CoroutineScope(dispatchers.io + SupervisorJob()) }

    companion object {
        const val REPLY_ACTION = "org.meshtastic.app.REPLY_ACTION"
        const val CONTACT_KEY = "contactKey"
        const val KEY_TEXT_REPLY = "key_text_reply"
    }

    override fun onReceive(context: Context, intent: Intent) {
        val remoteInput = RemoteInput.getResultsFromIntent(intent)

        if (remoteInput != null) {
            val contactKey = intent.getStringExtra(CONTACT_KEY).orEmpty()
            val message = remoteInput.getCharSequence(KEY_TEXT_REPLY)?.toString().orEmpty()

            val pendingResult = goAsync()
            scope.launch {
                try {
                    sendMessage(message, contactKey)
                    meshServiceNotifications.cancelMessageNotification(contactKey)
                } finally {
                    pendingResult.finish()
                }
            }
        }
    }

    private suspend fun sendMessage(str: String, contactKey: String) {
        // contactKey: unique contact key filter (channel)+(nodeId)
        val channel = contactKey.getOrNull(0)?.digitToIntOrNull()
        val dest = if (channel != null) contactKey.substring(1) else contactKey
        val p = DataPacket(dest, channel ?: 0, str)
        radioController.sendMessage(p)
    }
}
