package com.example.p3

import android.device.PrinterManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.Log
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonParser
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Helper class for interacting with the POS Printer.
 */
@Singleton
class PrinterHelper @Inject constructor() {
    private var printer: PrinterManager? = null
    private val gson = GsonBuilder().setPrettyPrinting().create()

    private val textPaint = Paint().apply {
        textSize = 24f
        color = Color.BLACK
        isAntiAlias = true
    }

    init {
        detectPrinter()
    }

    private fun detectPrinter() {
        try {
            // Attempt to instantiate the manager
            val manager = PrinterManager()
            
            try {
                // Test the implementation. 
                // We use getStatus() to see if it's the system implementation or the stub.
                val status = manager.getStatus()
                printer = manager
                Log.d("PrinterHelper", "PrinterManager initialized. Initial status: $status")
            } catch (e: Exception) {
                val errorMsg = e.cause?.message ?: e.message ?: ""
                Log.w("PrinterHelper", "getStatus() failed with: $errorMsg")
                
                if (errorMsg.contains("stub", ignoreCase = true)) {
                    Log.e("PrinterHelper", "CRITICAL: The SDK JAR is being bundled in your APK. You must Clean and Rebuild.")
                } else {
                    // If it's not a 'stub' error, it might just be the hardware state
                    printer = manager
                }
            }
        } catch (e: Throwable) {
            Log.e("PrinterHelper", "PrinterManager not available on this device: ${e.message}")
        }
    }

    fun getStatusMessage(code: Int): String {
        return when (code) {
            0 -> "Printer is healthy"
            -1 -> "No paper in printer"
            2 -> "Device is overheating"
            -3 -> "Battery is too low to print"
            else -> "Hardware error code: $code"
        }
    }

    fun printJson(jsonData: String, onStatus: (String) -> Unit) {
        try {
            val jsonElement: JsonElement = JsonParser.parseString(jsonData)
            val prettyJson = gson.toJson(jsonElement)
            printLines(prettyJson.split("\n"), onStatus)
        } catch (e: Exception) {
            onStatus("Invalid JSON data provided.")
        }
    }

    fun printLines(lines: List<String>, onStatus: (String) -> Unit) {
        if (printer == null) {
            detectPrinter()
        }

        val currentPrinter = printer
        if (currentPrinter == null) {
            onStatus("Printer hardware not supported or SDK issue.")
            return
        }

        Log.d("PrinterHelper", "Starting print job...")
        var bitmap: Bitmap? = null
        try {
            currentPrinter.open()
            currentPrinter.setupPage(384, -1)
            currentPrinter.clearPage()

            val lineHeight = 32
            val totalHeight = (lines.size * lineHeight) + 40
            
            bitmap = Bitmap.createBitmap(384, totalHeight, Bitmap.Config.ARGB_8888)
            bitmap.eraseColor(Color.WHITE)
            val canvas = Canvas(bitmap)

            var yPos = 30f
            for (line in lines) {
                canvas.drawText(line, 10f, yPos, textPaint)
                yPos += lineHeight
            }

            currentPrinter.drawBitmap(bitmap, 0, 0)
            val printResult = currentPrinter.printPage(0)
            
            if (printResult == 0) {
                currentPrinter.paperFeed(20)
                onStatus("Print Job Completed Successfully")
            } else {
                onStatus(getStatusMessage(printResult))
            }

        } catch (e: Exception) {
            onStatus("Printer Error: ${e.localizedMessage}")
            Log.e("PrinterHelper", "Unexpected error during printing", e)
        } finally {
            bitmap?.recycle()
            try {
                currentPrinter.close()
            } catch (e: Throwable) {}
        }
    }

/*
     fun printText(): Int {
        val manager = printer
        val mCenterPaint  = Paint().apply {
            textSize = 30f
            color = Color.BLACK
        }
        var mBitmap: Bitmap? = null
        manager.setupPage(384, -1)
        manager.clearPage()

        val mconfig = Bitmap.Config.ARGB_8888
        mBitmap = Bitmap.createBitmap(384, 2000, mconfig)
        mBitmap.eraseColor(-0x1) // 0xffffffff

        val mCanvas = Canvas(mBitmap)

        mCanvas.drawText("سلام", 330f, 30f, mCenterPaint)
        mCanvas.drawText("حال شما خوب هست", 165f, 60f, mCenterPaint)
        mCanvas.drawText("سلام", 330f, 90f, mCenterPaint)
        mCanvas.drawText("حال شما خوب هست", 165f, 120f, mCenterPaint)

        var mirrored: Bitmap? = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.width, 130)
        manager.drawBitmap(mirrored, 0, 0)

        val ret = manager.printPage(0)
        manager.paperFeed(15)

        mBitmap?.let {
            it.recycle()
            mBitmap = null
        }

        mirrored?.let {
            it.recycle()
            mirrored = null
        }

        return ret
    }
*/
}
