package club.clubk.ktag.apps.konfigurator

import android.util.Log
import club.clubk.ktag.apps.core.ble.Packet
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

class MultiDeviceConfigurator(private val bleManager: BleManager) {

    // Mutex to ensure only one device configuration (advertise + scan for ack) happens at a time
    private val bleOperationMutex = Mutex()

    /**
     * Configures a list of devices sequentially in terms of BLE operations,
     * but the overall process can be managed as part of a larger concurrent workflow.
     *
     * @param deviceConfigs List of Pair<String, Packet.Parameters> for each device to configure.
     * @param onDeviceConfigured A callback invoked for each device with its address and success status.
     * @param onProgressUpdate A callback to report overall progress (e.g., "Configuring device X of Y").
     * @return A map of device addresses to their configuration success status.
     */
    suspend fun configureMultipleDevices(
        deviceConfigs: List<Pair<String, Packet.Parameters>>,
        onDeviceConfigured: suspend (deviceAddress: String, success: Boolean) -> Unit,
        onProgressUpdate: suspend (configuredCount: Int, totalCount: Int) -> Unit
    ): Map<String, Boolean> {
        val results = mutableMapOf<String, Boolean>()
        var configuredCount = 0
        val totalCount = deviceConfigs.size

        onProgressUpdate(configuredCount, totalCount)

        for ((targetAddress, configPacket) in deviceConfigs) {
            var success = false
            try {
                bleOperationMutex.withLock {
                    Log.i(
                        "MultiDeviceConfigurator",
                        "Attempting to configure $targetAddress"
                    )
                    success = bleManager.configureDevice(configPacket, targetAddress)
                }
            } catch (e: Exception) {
                Log.e(
                    "MultiDeviceConfigurator",
                    "Exception configuring $targetAddress",
                    e
                )
                success = false
            }

            results[targetAddress] = success
            configuredCount++
            onDeviceConfigured(targetAddress, success)
            onProgressUpdate(configuredCount, totalCount)

            if (success) {
                Log.i(
                    "MultiDeviceConfigurator",
                    "Successfully configured $targetAddress"
                )
            } else {
                Log.w(
                    "MultiDeviceConfigurator",
                    "Failed to configure $targetAddress"
                )
            }
        }
        return results
    }
}
