package club.clubk.ktag.apps.sharedservices

import android.util.Log
import org.json.JSONObject

/**
 * Handles MQTT synchronization of device info across devices.
 * Publishes info changes as retained messages and subscribes to receive updates.
 */
class DeviceInfoMqttSync(
    private val repository: DeviceInfoRepository
) : MqttMessageListener {

    companion object {
        private const val TAG = "DeviceInfoMqttSync"
        private const val QOS = 1
    }

    private val topic: String
        get() = "KTag/${SharedMqttClient.battlefield}/DeviceInfo"

    /**
     * Subscribe to device info topic via the shared MQTT client.
     */
    fun connect() {
        SharedMqttClient.subscribe(topic, this)
    }

    override fun onMessageReceived(topic: String, payload: ByteArray) {
        handleIncomingMessage(payload)
    }

    private fun handleIncomingMessage(payload: ByteArray) {
        try {
            val json = String(payload)
            val jsonObject = JSONObject(json)
            val incoming = mutableMapOf<String, DeviceInfo>()

            jsonObject.keys().forEach { key ->
                val infoObj = jsonObject.getJSONObject(key)
                incoming[key] = DeviceInfo(
                    name = infoObj.optString("name", ""),
                    userDefinedName = infoObj.optString("userDefinedName", ""),
                    deviceType = infoObj.optInt("deviceType", 0),
                    deviceTypeName = infoObj.optString("deviceTypeName", ""),
                    majorVersion = infoObj.optInt("majorVersion", 0),
                    minorVersion = infoObj.optInt("minorVersion", 0)
                )
            }

            if (incoming.isNotEmpty()) {
                Log.i(TAG, "Received ${incoming.size} device info entries from MQTT")
                repository.mergeInfo(incoming)
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to parse incoming device info: ${e.message}")
        }
    }

    /**
     * Publish current device info to MQTT as a retained message.
     */
    fun publishCurrentInfo() {
        val json = repository.getAllInfoAsJson()
        SharedMqttClient.publish(topic, json.toByteArray(), QOS, retained = true)
        Log.i(TAG, "Published device info to $topic")
    }

    /**
     * Cleanup MQTT resources.
     */
    fun cleanup() {
        SharedMqttClient.unsubscribe(topic, this)
    }
}
