package com.rosetta.messenger.network.connection

import android.content.Context
import android.os.Build
import com.rosetta.messenger.network.DeviceEntry
import com.rosetta.messenger.network.DeviceResolveSolution
import com.rosetta.messenger.network.HandshakeDevice
import com.rosetta.messenger.network.Packet
import com.rosetta.messenger.network.PacketDeviceList
import java.security.SecureRandom
import kotlinx.coroutines.flow.StateFlow

class DeviceRuntimeService(
    private val getAppContext: () -> Context?,
    private val sendPacket: (Packet) -> Unit,
    private val devicePrefsName: String = "rosetta_protocol",
    private val deviceIdKey: String = "device_id",
    private val deviceIdLength: Int = 128
) {
    private val verificationService = DeviceVerificationService()

    val devices: StateFlow<List<DeviceEntry>> = verificationService.devices
    val pendingDeviceVerification: StateFlow<DeviceEntry?> =
        verificationService.pendingDeviceVerification

    fun handleDeviceList(packet: PacketDeviceList) {
        verificationService.handleDeviceList(packet)
    }

    fun acceptDevice(deviceId: String) {
        sendPacket(
            verificationService.buildResolvePacket(
                deviceId = deviceId,
                solution = DeviceResolveSolution.ACCEPT
            )
        )
    }

    fun declineDevice(deviceId: String) {
        sendPacket(
            verificationService.buildResolvePacket(
                deviceId = deviceId,
                solution = DeviceResolveSolution.DECLINE
            )
        )
    }

    fun resolvePushDeviceId(): String {
        return getAppContext()?.let(::getOrCreateDeviceId).orEmpty()
    }

    fun buildHandshakeDevice(): HandshakeDevice {
        val context = getAppContext()
        val deviceId = if (context != null) getOrCreateDeviceId(context) else generateDeviceId()
        val manufacturer = Build.MANUFACTURER.orEmpty().trim()
        val model = Build.MODEL.orEmpty().trim()
        val name =
            listOf(manufacturer, model)
                .filter { it.isNotBlank() }
                .distinct()
                .joinToString(" ")
                .ifBlank { "Android Device" }
        val os = "Android ${Build.VERSION.RELEASE ?: "Unknown"}"

        return HandshakeDevice(
            deviceId = deviceId,
            deviceName = name,
            deviceOs = os
        )
    }

    fun clear() {
        verificationService.clear()
    }

    private fun getOrCreateDeviceId(context: Context): String {
        val prefs = context.getSharedPreferences(devicePrefsName, Context.MODE_PRIVATE)
        val cached = prefs.getString(deviceIdKey, null)
        if (!cached.isNullOrBlank()) {
            return cached
        }
        val newId = generateDeviceId()
        prefs.edit().putString(deviceIdKey, newId).apply()
        return newId
    }

    private fun generateDeviceId(): String {
        val chars = "abcdefghijklmnopqrstuvwxyz0123456789"
        val random = SecureRandom()
        return buildString(deviceIdLength) {
            repeat(deviceIdLength) {
                append(chars[random.nextInt(chars.length)])
            }
        }
    }
}
