package com.example.ops_android.printer

import com.example.ops_android.data.model.Item
import com.example.ops_android.data.model.PurchaseOrder
import com.example.ops_android.data.model.WorkOrder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext

object PrintHelper {

    private val printMutex = Mutex()

    suspend fun printOrderLabel(
        printerManager: PrinterManager,
        order: PurchaseOrder,
        blackMarkEnabled: Boolean = true,
        unwindMm: Int = 40
    ): Result<Unit> = printMutex.withLock {
        withContext(Dispatchers.IO) {
            try {
                printerManager.initDevice().onFailure { return@withContext Result.failure(it) }
                printerManager.setFontSize(24)
                printerManager.setBold(true)
                printerManager.addText("采购单: ${order.title ?: "-"}\n")
                printerManager.setFontSize(20)
                printerManager.setBold(false)
                if (order.id > 0) {
                    printerManager.addBarcode("PO-${order.id}")
                }
                if (blackMarkEnabled) {
                    printerManager.addLineFeed(2)
                    printerManager.enableMarkDetection(true)
                } else {
                    printerManager.addLineFeed((unwindMm / 7).toInt().coerceAtLeast(2))
                }
                printerManager.commit()
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    suspend fun printWorkOrderLabel(
        printerManager: PrinterManager,
        workOrder: WorkOrder,
        blackMarkEnabled: Boolean = true,
        unwindMm: Int = 40
    ): Result<Unit> = printMutex.withLock {
        withContext(Dispatchers.IO) {
            try {
                printerManager.initDevice().onFailure { return@withContext Result.failure(it) }
                printerManager.setFontSize(24)
                printerManager.setBold(true)
                printerManager.addText("工单: ${workOrder.title ?: "-"}\n")
                printerManager.setFontSize(20)
                printerManager.setBold(false)
                if (workOrder.id > 0) {
                    printerManager.addBarcode("WO-${workOrder.id}")
                }
                if (blackMarkEnabled) {
                    printerManager.addLineFeed(2)
                    printerManager.enableMarkDetection(true)
                } else {
                    printerManager.addLineFeed((unwindMm / 7).toInt().coerceAtLeast(2))
                }
                printerManager.commit()
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    suspend fun printItemLabel(
        printerManager: PrinterManager,
        item: Item,
        blackMarkEnabled: Boolean = true,
        unwindMm: Int = 40
    ): Result<Unit> = printMutex.withLock {
        withContext(Dispatchers.IO) {
            try {
                printerManager.initDevice().onFailure { return@withContext Result.failure(it) }
                printerManager.setFontSize(24)
                printerManager.setBold(true)
                printerManager.addText("${item.name ?: "-"}\n")
                printerManager.setFontSize(18)
                printerManager.setBold(false)
                item.serial_number?.let { printerManager.addText("编号: $it\n") }
                if (item.id > 0) {
                    printerManager.addBarcode("ITEM-${item.id}")
                }
                if (blackMarkEnabled) {
                    printerManager.addLineFeed(2)
                    printerManager.enableMarkDetection(true)
                } else {
                    printerManager.addLineFeed((unwindMm / 7).toInt().coerceAtLeast(2))
                }
                printerManager.commit()
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    suspend fun printContainerLabel(
        printerManager: PrinterManager,
        containerName: String,
        barcode: String? = null,
        blackMarkEnabled: Boolean = true,
        unwindMm: Int = 40
    ): Result<Unit> = printMutex.withLock {
        withContext(Dispatchers.IO) {
            try {
                printerManager.initDevice().onFailure { return@withContext Result.failure(it) }
                printerManager.setFontSize(24)
                printerManager.setBold(true)
                printerManager.addText("容器: $containerName\n")
                if (barcode != null) {
                    printerManager.setFontSize(18)
                    printerManager.setBold(false)
                    printerManager.addBarcode(barcode)
                }
                if (blackMarkEnabled) {
                    printerManager.addLineFeed(2)
                    printerManager.enableMarkDetection(true)
                } else {
                    printerManager.addLineFeed((unwindMm / 7).toInt().coerceAtLeast(2))
                }
                printerManager.commit()
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }
}
