package com.centralcloud.oncall.sms

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.provider.Telephony
import android.util.Log
import androidx.work.Data
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import java.util.UUID

/**
 * Receives every SMS_RECEIVED broadcast, filters by the SmsRelayPreferences
 * whitelist, and hands matching messages off to SmsForwardWorker for delivery
 * to centralcloud-ops.
 *
 * Multi-part SMS arrive as a single intent containing multiple PDUs. We
 * concatenate their bodies but only use the first message's sender/timestamp
 * (which is what the carrier presents anyway).
 *
 * Anything goes wrong (no perms, no config, no whitelist hit, intent
 * malformed) → log + drop silently. This receiver MUST NOT raise — it's on
 * the SMS_RECEIVED hot path.
 */
class SmsRelayReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        try {
            if (intent.action != Telephony.Sms.Intents.SMS_RECEIVED_ACTION) return

            val prefs = SmsRelayPreferences(context)
            if (!prefs.enabled) return

            val messages = Telephony.Sms.Intents.getMessagesFromIntent(intent)
                ?: return
            if (messages.isEmpty()) return

            val sender = messages[0].displayOriginatingAddress
                ?: messages[0].originatingAddress
                ?: return
            if (!prefs.shouldForward(sender)) return

            val body = messages.joinToString("") { it.messageBody.orEmpty() }
            val receivedAtMs = messages[0].timestampMillis
            val clientMessageId = UUID.randomUUID().toString()

            val data = Data.Builder()
                .putString(SmsForwardWorker.KEY_FROM, sender)
                .putString(SmsForwardWorker.KEY_BODY, body)
                .putLong(SmsForwardWorker.KEY_RECEIVED_AT_MS, receivedAtMs)
                .putString(SmsForwardWorker.KEY_CLIENT_MESSAGE_ID, clientMessageId)
                .build()

            val req = OneTimeWorkRequestBuilder<SmsForwardWorker>()
                .setInputData(data)
                .setConstraints(SmsForwardWorker.connectedConstraints())
                .setBackoffCriteria(
                    androidx.work.BackoffPolicy.EXPONENTIAL,
                    SmsForwardWorker.INITIAL_BACKOFF_SECONDS,
                    java.util.concurrent.TimeUnit.SECONDS
                )
                .addTag(SmsForwardWorker.TAG)
                .build()

            WorkManager
                .getInstance(context.applicationContext)
                .enqueueUniqueWork(
                    "sms-relay-$clientMessageId",
                    androidx.work.ExistingWorkPolicy.KEEP,
                    req
                )

            Log.d(TAG, "queued sms-relay: from=$sender bytes=${body.length} cid=$clientMessageId")
        } catch (t: Throwable) {
            Log.e(TAG, "sms-relay receive failed", t)
        }
    }

    companion object {
        private const val TAG = "SmsRelayReceiver"
    }
}
