// Copyright (C) 2026 Jason M. Schwefel. All Rights Reserved.
package com.coldboreballisticsllc.scopedope.data.printer.niimbot

import android.graphics.Bitmap
import com.coldboreballisticsllc.scopedope.domain.printer.ConnectedDeviceInfo
import com.coldboreballisticsllc.scopedope.domain.printer.PrinterSource
import com.coldboreballisticsllc.scopedope.domain.printer.PrinterState
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Routes print operations to the correct Niimbot driver based on the target device's
 * Bluetooth name. The B21 Pro is selected when the BT name contains "B21"; otherwise
 * the B1 driver is used as default.
 *
 * UUIDs in [NiimbotB21ProDriver] are marked UNVERIFIED — replace them after hardware
 * capture before shipping B21 Pro support (GH #1 / #77).
 */
@Singleton
class NiimbotPrinterRouter @Inject constructor(
    private val b1:     NiimbotB1Driver,
    private val b21Pro: NiimbotB21ProDriver,
) : PrinterSource {

    private fun driverFor(mac: String?): PrinterSource {
        if (mac == null) return b1
        val btName = b1.connectedDeviceInfo.value?.mac?.let { if (it == mac) b1.connectedDeviceInfo.value?.btName else null }
            ?: b21Pro.connectedDeviceInfo.value?.mac?.let { if (it == mac) b21Pro.connectedDeviceInfo.value?.btName else null }
            ?: mac
        return if (btName.contains("B21", ignoreCase = true)) b21Pro else b1
    }

    private val active: PrinterSource
        get() {
            if (b21Pro.connectedDeviceInfo.value != null) return b21Pro
            if (b1.connectedDeviceInfo.value != null) return b1
            return b1
        }

    override val displayName: String
        get() = active.displayName

    override val nativeDpi: Int
        get() = active.nativeDpi

    override val state: StateFlow<PrinterState>
        get() = active.state

    override val connectedDeviceInfo: StateFlow<ConnectedDeviceInfo?>
        get() = active.connectedDeviceInfo

    override suspend fun connect(targetMac: String?) {
        // Route to B21 Pro if BT name contains "B21", otherwise B1.
        // When targetMac is null (scan mode), try B1 first; B21 Pro scan requires explicit selection.
        val driver = driverFor(targetMac)
        driver.connect(targetMac)
    }

    override suspend fun disconnect() {
        b1.disconnect()
        b21Pro.disconnect()
    }

    override suspend fun print(bitmap: Bitmap) = active.print(bitmap)
}
