package com.centralcloud.oncall.sms

import android.content.Context
import android.content.SharedPreferences

/**
 * SharedPreferences-backed config for the SMS-relay feature.
 *
 * Strict opt-in: relay is OFF until [enabled] is set true AND the [whitelist] is
 * non-empty AND a base URL + device id are configured. A missing/invalid value
 * silently drops the SMS (never crashes the boot-time SMS receiver).
 *
 * In this commit there is no settings UI yet — set values via adb shell or a
 * future preferences screen:
 *   adb shell am start-activity ... (or use a dedicated settings activity)
 *   adb shell input keyevent ... (or edit SharedPreferences directly)
 *
 * Whitelist matching is exact-string on the SMS sender address as Android
 * reports it (typically E.164, sometimes a short code or alphanumeric ID).
 */
class SmsRelayPreferences(context: Context) {
    private val prefs: SharedPreferences =
        context.getSharedPreferences(FILE, Context.MODE_PRIVATE)

    var enabled: Boolean
        get() = prefs.getBoolean(KEY_ENABLED, false)
        set(value) = prefs.edit().putBoolean(KEY_ENABLED, value).apply()

    /** Base URL of centralcloud-ops, e.g. "https://ops.centralcloud.com". No trailing slash. */
    var baseUrl: String
        get() = prefs.getString(KEY_BASE_URL, "")!!.trimEnd('/')
        set(value) = prefs.edit().putString(KEY_BASE_URL, value.trimEnd('/')).apply()

    /** Device id token registered in centralcloud-ops `push_subscriptions`. */
    var deviceId: String
        get() = prefs.getString(KEY_DEVICE_ID, "")!!
        set(value) = prefs.edit().putString(KEY_DEVICE_ID, value).apply()

    /**
     * Set of sender addresses to forward. Anything not in this set is ignored.
     * Empty set ⇒ forward nothing (safe default).
     *
     * Storage format is a single comma-separated string so an EditTextPreference
     * in [SmsRelaySettingsActivity] can edit it directly. Whitespace around
     * entries is stripped on read.
     */
    var whitelist: Set<String>
        get() = prefs.getString(KEY_WHITELIST, "")!!
            .splitToSequence(',')
            .map { it.trim() }
            .filter { it.isNotEmpty() }
            .toSet()
        set(value) = prefs.edit()
            .putString(KEY_WHITELIST, value.joinToString(","))
            .apply()

    /** Epoch-ms of the last SUCCESSFUL forward (200 from the server), or 0 if never. */
    var lastForwardAtMs: Long
        get() = prefs.getLong(KEY_LAST_FORWARD_AT_MS, 0L)
        set(value) = prefs.edit().putLong(KEY_LAST_FORWARD_AT_MS, value).apply()

    /** Rolling 24h forward-failure counter (best-effort; reset by DeviceHeartbeatWorker). */
    var failureCount24h: Int
        get() = prefs.getInt(KEY_FAILURE_COUNT_24H, 0)
        set(value) = prefs.edit().putInt(KEY_FAILURE_COUNT_24H, value).apply()

    /** Ops-native push config discovered from /api/android/config. */
    var nativePushEnabled: Boolean
        get() = prefs.getBoolean(KEY_NATIVE_PUSH_ENABLED, false)
        set(value) = prefs.edit().putBoolean(KEY_NATIVE_PUSH_ENABLED, value).apply()

    var nativePushTopic: String
        get() = prefs.getString(KEY_NATIVE_PUSH_TOPIC, "")!!
        set(value) = prefs.edit().putString(KEY_NATIVE_PUSH_TOPIC, value).apply()

    var nativePushStreamUrl: String
        get() = prefs.getString(KEY_NATIVE_PUSH_STREAM_URL, "")!!
        set(value) = prefs.edit().putString(KEY_NATIVE_PUSH_STREAM_URL, value).apply()

    var nativePushMessagesUrl: String
        get() = prefs.getString(KEY_NATIVE_PUSH_MESSAGES_URL, "")!!
        set(value) = prefs.edit().putString(KEY_NATIVE_PUSH_MESSAGES_URL, value).apply()

    var nativePushLastSeenAt: String
        get() = prefs.getString(KEY_NATIVE_PUSH_LAST_SEEN_AT, "")!!
        set(value) = prefs.edit().putString(KEY_NATIVE_PUSH_LAST_SEEN_AT, value).apply()

    fun bumpFailureCount() {
        failureCount24h = failureCount24h + 1
    }

    fun resetFailureCount() {
        failureCount24h = 0
    }

    /**
     * Returns true iff this SMS should be forwarded right now (relay is
     * enabled, fully configured, and the sender is in the whitelist).
     */
    fun shouldForward(sender: String?): Boolean {
        if (!enabled) return false
        if (baseUrl.isBlank() || deviceId.isBlank()) return false
        if (sender.isNullOrBlank()) return false
        return whitelist.contains(sender)
    }

    companion object {
        private const val FILE = "sms_relay_prefs"
        private const val KEY_ENABLED = "enabled"
        private const val KEY_BASE_URL = "base_url"
        private const val KEY_DEVICE_ID = "device_id"
        private const val KEY_WHITELIST = "whitelist"
        private const val KEY_LAST_FORWARD_AT_MS = "last_forward_at_ms"
        private const val KEY_FAILURE_COUNT_24H = "failure_count_24h"
        private const val KEY_NATIVE_PUSH_ENABLED = "native_push_enabled"
        private const val KEY_NATIVE_PUSH_TOPIC = "native_push_topic"
        private const val KEY_NATIVE_PUSH_STREAM_URL = "native_push_stream_url"
        private const val KEY_NATIVE_PUSH_MESSAGES_URL = "native_push_messages_url"
        private const val KEY_NATIVE_PUSH_LAST_SEEN_AT = "native_push_last_seen_at"
    }
}
