# edited by glg
try:
    from escpos.printer import Usb, Network
    ESCPOS_PRINTER_AVAILABLE = True
except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
    ESCPOS_PRINTER_AVAILABLE = False

try:
    import usb.core
    USB_CORE_AVAILABLE = True
except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
    USB_CORE_AVAILABLE = False


class PrinterIOService:
    def test_connection(self, koneksi, address):
        """
        Test koneksi printer dan kirim cetak dummy.
        koneksi: usb | lan
        address: "VID:PID" (untuk USB) atau "IP:PORT" (untuk LAN)
        Return: (status: bool, error_code: str)
        """
        try:
            if not ESCPOS_PRINTER_AVAILABLE:
                return False, "ERR_DEPENDENCY_MISSING"
            if (koneksi or "").lower() == "usb":
                if not USB_CORE_AVAILABLE:
                    return False, "ERR_USB_DEPENDENCY_MISSING"
                try:
                    vid, pid = address.split(":")
                    vid, pid = int(vid, 16), int(pid, 16)
                except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
                    return False, "ERR_FORMAT_USB"

                try:
                    dev = usb.core.find(idVendor=vid, idProduct=pid)
                except Exception as exc:
                    if "No backend available" in str(exc):
                        return False, "ERR_USB_BACKEND_MISSING"
                    return False, "ERR_USB_LOOKUP_FAIL"
                if dev is None:
                    return False, "ERR_USB_NOT_FOUND"

                try:
                    printer = Usb(vid, pid)
                    printer.text("=== TEST PRINT USB ===\n")
                    printer.text("Berhasil terkoneksi via USB!\n\n")
                    printer.cut()
                except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
                    return False, "ERR_USB_PRINT_FAIL"
                return True, "OK_USB"

            if (koneksi or "").lower() == "lan":
                try:
                    ip, port = address.split(":")
                    port = int(port)
                except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
                    return False, "ERR_FORMAT_LAN"

                try:
                    printer = Network(ip, port=port, timeout=3)
                    printer.text("=== TEST PRINT LAN ===\n")
                    printer.text("Berhasil terkoneksi via Network!\n\n")
                    printer.cut()
                except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
                    return False, "ERR_LAN_PRINT_FAIL"
                return True, "OK_LAN"

            return False, "ERR_CONN_TYPE_UNSUPPORTED"

        except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
            return False, "ERR_UNKNOWN"
