package com.cpm.lorealbaMabeline.printer;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.hoin.btsdk.BluetoothService;
import com.cpm.lorealbaMabeline.Database.Lorealba_Database;
import com.cpm.lorealbaMabeline.R;
import com.cpm.lorealbaMabeline.constant.CommonFunctions;
import com.cpm.lorealbaMabeline.constant.CommonString;
import com.cpm.lorealbaMabeline.delegates.PrefHelper;
import com.cpm.lorealbaMabeline.gsonGetterSetter.InvoiceGetterSetter;
import com.cpm.lorealbaMabeline.gsonGetterSetter.JourneyPlan;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;

public class PrinterActivity extends AppCompatActivity {
    ArrayList<InvoiceGetterSetter> invoice_List = new ArrayList<>();
    InvoiceGetterSetter object = new InvoiceGetterSetter();
    String store_name, counter_name, store_address, visit_date, user_name, countrId, consumerReturnflag, counter_code;
    JourneyPlan storeDataObject = new JourneyPlan();
    private static final int REQUEST_CONNECT_DEVICE = 1;  //»ñÈ¡Éè±¸ÏûÏ¢
    private static final int REQUEST_ENABLE_BT = 2;
    BluetoothService mService = null;
    BluetoothDevice con_dev = null;
    Lorealba_Database db;
    Button btnSearch;
    Button btnSend;
    Context context;
    int receipt_count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_printer);
        context = this;
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        Objects.requireNonNull(getSupportActionBar()).setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        if (!CommonFunctions.isTablet(context)) {
            toolbar.setTitleTextAppearance(context, R.style.changestext_sizefor_mobile);
        }
        db = new Lorealba_Database(context);
        db.open();
        btnSearch = (Button) findViewById(R.id.btnSearch);
        btnSearch.setOnClickListener(new ClickEvent());
        btnSend = (Button) findViewById(R.id.btnSend);
        SharedPreferences preferences = PrefHelper.getPrefs(context);
        countrId = preferences.getString(CommonString.KEY_COUNTER_ID, "");
        counter_code = preferences.getString(CommonString.KEY_COUNTER_CODE, "");
        visit_date = preferences.getString(CommonString.KEY_DATE, "");
        store_name = preferences.getString(CommonString.KEY_STORE_NAME, "");
        store_address = preferences.getString(CommonString.KEY_STORE_ADDRESS, "");
        user_name = preferences.getString(CommonString.KEY_USERNAME, "");
        setTitle("Printer -" + user_name);
        btnSend.setOnClickListener(new ClickEvent());
        consumerReturnflag = getIntent().getStringExtra(CommonString.TAG_FOR_RETURN);
        if (consumerReturnflag != null && consumerReturnflag.equals("1")) {
            object = (InvoiceGetterSetter) getIntent().getSerializableExtra(CommonString.TAG_HEADER_OBJECT);
        }
        invoice_List = (ArrayList<InvoiceGetterSetter>) getIntent().getSerializableExtra(CommonString.TAG_OBJECT);
        if (invoice_List != null && !invoice_List.isEmpty()) {
            user_name = invoice_List.get(0).getUserName();
        }

        receipt_count = db.receipt_count_userwise(visit_date, countrId, user_name);
        receipt_count = receipt_count + 1;
        db.open();
        storeDataObject = db.getspecific_storenamewith_counter_name(visit_date, countrId, user_name);
        if (storeDataObject != null && storeDataObject.getStoreName() != null) {
            store_name = storeDataObject.getStoreName();
            counter_name = storeDataObject.getCounterName();
            store_address = "    " + storeDataObject.getAddress() + " , " + storeDataObject.getCityName();
        } else {
            counter_name = "";
            store_name = "";
            store_address = "";
        }
        btnSend.setEnabled(false);
        requestBluetooth();
        mService = new BluetoothService(context, mHandler);
        if (!mService.isAvailable()) {
            Toast.makeText(context, "Bluetooth is not available", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!mService.isBTopen()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mService != null)
            mService.stop();
        mService = null;
    }

    class ClickEvent implements View.OnClickListener {
        @SuppressLint("NonConstantResourceId")
        public void onClick(View v) {
            String msg = "";

            if (v.getId() == R.id.btnSearch) {
                Intent serverIntent = new Intent(getApplicationContext(), DeviceListActivity.class);      //ÔËÐÐÁíÍâÒ»¸öÀàµÄ»î¶¯
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
            } else if (v.getId() == R.id.btnSend) {
                //msg = edtContext.getText().toString();
                // Bold format center:
                if (consumerReturnflag != null && consumerReturnflag.equals("1")) {
                    msg = "Store : " + store_name + " Counter : " + counter_name + " Counter Code : " + counter_code;
                    mService.sendMessage(msg + "\n" + "   " + store_address, "GBK");
                    String pinkSlip = "Consumer Return Slip - " + object.getReccept_count();
                    mService.sendMessage(pinkSlip, "GBK");
                    // Bold underlined format with right alignment:
                    String for_date = "Date : " + visit_date + "\n\nCustomer Name : " + object.getCustomer_name()
                            + "\nMobile No. : " + object.getMobile_no() + "\n Bill No. : " + object.getConsumer_return_bill_no() + "\n" + "Ba Name : " + user_name;

                    mService.sendMessage(for_date, "GBK");
                    double total_INR_value = 0.0, total = 0.0;
                    String productPrint = "", ean_code, quantity1, discount = "";
                    for (int k = 0; k < invoice_List.size(); k++) {
                        int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                        double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                        amount = amount * quantity;
                        invoice_List.get(k).setTotal_amount("" + amount);
                        productPrint = invoice_List.get(k).getProduct();
                        total_INR_value = total_INR_value + Double.parseDouble(invoice_List.get(k).getTotal_amount());
                        ean_code = invoice_List.get(k).getScan_ean_code_or_enterd_ean_code();
                        quantity1 = "QTY : " + invoice_List.get(k).getQuantity() + " Rate : " + invoice_List.get(k).getProduct_rate() + " Amount : " + invoice_List.get(k).getTotal_amount();
                        mService.sendMessage("Product : " + productPrint + "\n" + "Ean Code : " + ean_code + "\n" + quantity1 + "\n" + "Return Reason : " + invoice_List.get(k).getCon_return_reason(), "GBK");
                        mService.sendMessage(discount, "GBK");
                    }

                    total = total_INR_value;
                    mService.sendMessage("Total Amount : " + total + "\n", "GBK");

                } else {
                    ////print data of consumer sales data
                    msg = "Store : " + store_name + " Counter : " + counter_name;
                    mService.sendMessage(msg + "\n" + store_address, "GBK");
                    String pinkSlip = "Pink Slip - " + receipt_count;
                    mService.sendMessage(pinkSlip, "GBK");
                    // Bold underlined format with right alignment:
                    String for_date = "Date : " + visit_date + "\n\nCustomer Name : " + invoice_List.get(0).getCustomer_name() + "\nMobile No. : " + invoice_List.get(0).getMobile_no() + "\n" + "Ba Name : " + user_name;
                    mService.sendMessage(for_date, "GBK");

                    double cCom = 0.0, total_INR_value = 0.0, total = 0.0, off_worth_total = 0.0, worth_total = 0.0;
                    ;
                    String productPrint = "", ean_code, quantity1, discount = "";
                    for (int k = 0; k < invoice_List.size(); k++) {
                        if (!invoice_List.get(k).isPromo_flag()) {

                            if (invoice_List.get(k).getDiscount() != 0.0) {
                                int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                amount = amount * quantity;
                                invoice_List.get(k).setTotal_amount("" + amount);
                                cCom = cCom + ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                            } else {

                                int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                amount = amount * quantity;
                                invoice_List.get(k).setTotal_amount("" + amount);
                            }

                            invoice_List.get(k).setStore_name(store_name);
                            invoice_List.get(k).setStore_address(store_address);

                            productPrint = invoice_List.get(k).getProduct();
                            double amount_ofproduct = ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                            amount_ofproduct = (Double.parseDouble(invoice_List.get(k).getTotal_amount())) - amount_ofproduct;
                            total_INR_value = total_INR_value + Double.parseDouble(invoice_List.get(k).getTotal_amount());
                            ean_code = invoice_List.get(k).getScan_ean_code_or_enterd_ean_code();
                            quantity1 = "QTY : " + invoice_List.get(k).getQuantity() + " Rate : " + invoice_List.get(k).getProduct_rate() + " Amount : " + invoice_List.get(k).getTotal_amount();
                            mService.sendMessage(productPrint + "\n" + "Product Type : " + invoice_List.get(k).getStr_invoiceType() + "\n" + ean_code + "\n" + quantity1, "GBK");
                            String string = invoice_List.get(k).getDiscount().toString();
                            if (invoice_List.get(k).getDiscount() == 0.0 || invoice_List.get(k).getDiscount() == 0) {
                                discount = "Actual Price : " + (Double.parseDouble(invoice_List.get(k).getTotal_amount()));
                            } else {
                                discount = string.substring(string.length() - 1) + "0% Discount - " + ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount()) + " Actual Price : " + (Double.parseDouble(invoice_List.get(k).getTotal_amount()) -
                                        ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount()));
                            }

                            mService.sendMessage(discount, "GBK");
                        } else {
                            if (invoice_List.get(k).getPromo_type().equalsIgnoreCase("OffProduct")) {
                                if (invoice_List.get(k).getDiscount() != 0.0) {
                                    int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                    double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                    amount = amount * quantity;
                                    invoice_List.get(k).setTotal_amount("" + amount);
                                    cCom = cCom + ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                                } else {

                                    int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                    double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                    amount = amount * quantity;
                                    invoice_List.get(k).setTotal_amount("" + amount);
                                }

                                invoice_List.get(k).setStore_name(store_name);
                                invoice_List.get(k).setStore_address(store_address);

                                productPrint = invoice_List.get(k).getProduct();
                                double amount_ofproduct = ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                                amount_ofproduct = (Double.parseDouble(invoice_List.get(k).getTotal_amount())) - amount_ofproduct;
                                total_INR_value = total_INR_value + Double.parseDouble(invoice_List.get(k).getTotal_amount());
                                ean_code = invoice_List.get(k).getScan_ean_code_or_enterd_ean_code();
                                quantity1 = "QTY : " + invoice_List.get(k).getQuantity() + " Rate : " + invoice_List.get(k).getProduct_rate() + " Amount : " + invoice_List.get(k).getTotal_amount();
                                mService.sendMessage(productPrint + "\n" + "Product Type : " + invoice_List.get(k).getPromo_type() + "\n" + ean_code + "\n" + quantity1, "GBK");
                                String string = invoice_List.get(k).getDiscount().toString();
                                if (invoice_List.get(k).getDiscount() == 0.0 || invoice_List.get(k).getDiscount() == 0) {
                                    discount = "Actual Price : " + (Double.parseDouble(invoice_List.get(k).getTotal_amount()));
                                } else {
                                    discount = string.substring(string.length() - 1) + "0% Discount - " + ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount()) + " Actual Price : " + (Double.parseDouble(invoice_List.get(k).getTotal_amount()) -
                                            ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount())) + "";
                                }
                                total_INR_value = total_INR_value - Integer.parseInt(invoice_List.get(k).getSkuType());
                                mService.sendMessage(discount, "GBK");
                            } else if (invoice_List.get(k).getPromo_type().equalsIgnoreCase("OffWorth")) {
                                if (invoice_List.get(k).getDiscount() != 0.0) {
                                    int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                    double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                    amount = amount * quantity;
                                    invoice_List.get(k).setTotal_amount("" + amount);
                                    cCom = cCom + ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                                } else {

                                    int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                    double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                    amount = amount * quantity;
                                    invoice_List.get(k).setTotal_amount("" + amount);
                                }

                                invoice_List.get(k).setStore_name(store_name);
                                invoice_List.get(k).setStore_address(store_address);

                                double amount_ofproduct = ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                                amount_ofproduct = (Double.parseDouble(invoice_List.get(k).getTotal_amount())) - amount_ofproduct;
                                total_INR_value = total_INR_value + Double.parseDouble(invoice_List.get(k).getTotal_amount());
                                ean_code = invoice_List.get(k).getScan_ean_code_or_enterd_ean_code();
                                mService.sendMessage("Applied Promo - " + invoice_List.get(k).getPromotion_name() + " - " + "Discounted Rs - " + invoice_List.get(k).getProduct(), "GBK");
                                off_worth_total = off_worth_total + Double.parseDouble(invoice_List.get(k).getProduct());

                            } else if (invoice_List.get(k).getPromo_type().equalsIgnoreCase("Worth")) {
                                if (invoice_List.get(k).getDiscount() != 0.0) {
                                    int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                    double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                    amount = amount * quantity;
                                    invoice_List.get(k).setTotal_amount("" + amount);
                                    cCom = cCom + ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                                } else {

                                    int quantity = Integer.parseInt(invoice_List.get(k).getQuantity());
                                    double amount = Double.parseDouble(invoice_List.get(k).getProduct_rate());
                                    amount = amount * quantity;
                                    invoice_List.get(k).setTotal_amount("" + amount);
                                }

                                invoice_List.get(k).setStore_name(store_name);
                                invoice_List.get(k).setStore_address(store_address);

                                double amount_ofproduct = ((Double.parseDouble(invoice_List.get(k).getTotal_amount())) * invoice_List.get(k).getDiscount());
                                amount_ofproduct = (Double.parseDouble(invoice_List.get(k).getTotal_amount())) - amount_ofproduct;
                                total_INR_value = total_INR_value + Double.parseDouble(invoice_List.get(k).getTotal_amount());
                                ean_code = invoice_List.get(k).getScan_ean_code_or_enterd_ean_code();
                                mService.sendMessage("Applied Promo - " + invoice_List.get(k).getPromotion_name() + " - " + "Discounted Rs - " + invoice_List.get(k).getProduct(), "GBK");
                                worth_total = worth_total + Double.parseDouble(invoice_List.get(k).getProduct());
                            }
                        }
                    }

                    total = total_INR_value - cCom;
                    total = total - off_worth_total;
                    total = total - worth_total;

                    mService.sendMessage("Total Amount : " + total + "\n", "GBK");
                }
            }
        }
    }

    public void writeWithFormat(byte[] buffer, final byte[] pFormat, final byte[] pAlignment) {
        // Notify printer it should be printed with given alignment:
        mService.write(pAlignment);
        // Notify printer it should be printed in the given format://±¶¿í¡¢±¶¸ßÄ£Ê½
        mService.write(pFormat);
        // Write the actual data://±¶¿í¡¢±¶¸ßÄ£Ê½
        mService.write(buffer);           //±¶¿í¡¢±¶¸ßÄ£Ê½
        //mService.sendMessage("Congratulations!\n", "GBK");
    }

    /**
     * ´´½¨Ò»¸öHandlerÊµÀý£¬ÓÃÓÚ½ÓÊÕBluetoothServiceÀà·µ»Ø»ØÀ´µÄÏûÏ¢
     */
    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @SuppressLint("HandlerLeak")
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BluetoothService.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BluetoothService.STATE_CONNECTED:   //ÒÑÁ¬½Ó
                            Toast.makeText(getApplicationContext(), "Connect successful",
                                    Toast.LENGTH_SHORT).show();
                            btnSend.setEnabled(true);
                            break;
                        case BluetoothService.STATE_CONNECTING:  //ÕýÔÚÁ¬½Ó
                            //test("À¶ÑÀµ÷ÊÔ", "ÕýÔÚÁ¬½Ó.....");
                            break;
                        case BluetoothService.STATE_LISTEN:     //¼àÌýÁ¬½ÓµÄµ½À´
                        case BluetoothService.STATE_NONE:
                            //test("À¶ÑÀµ÷ÊÔ", "µÈ´ýÁ¬½Ó.....");
                            break;
                    }
                    break;
                case BluetoothService.MESSAGE_CONNECTION_LOST:    //À¶ÑÀÒÑ¶Ï¿ªÁ¬½Ó
                    Toast.makeText(getApplicationContext(), "Device connection was lost",
                            Toast.LENGTH_SHORT).show();
                    btnSend.setEnabled(false);

                    break;
                case BluetoothService.MESSAGE_UNABLE_CONNECT:     //ÎÞ·¨Á¬½ÓÉè±¸
                    Toast.makeText(getApplicationContext(), "Unable to connect device",
                            Toast.LENGTH_SHORT).show();
                    break;
            }
        }

    };

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_ENABLE_BT:      //ÇëÇó´ò¿ªÀ¶ÑÀ
                if (resultCode == Activity.RESULT_OK) {   //À¶ÑÀÒÑ¾­´ò¿ª
                    Toast.makeText(this, "Bluetooth open successful", Toast.LENGTH_LONG).show();
                }
                break;
            case REQUEST_CONNECT_DEVICE:     //ÇëÇóÁ¬½ÓÄ³Ò»À¶ÑÀÉè±¸
                if (resultCode == Activity.RESULT_OK) {   //ÒÑµã»÷ËÑË÷ÁÐ±íÖÐµÄÄ³¸öÉè±¸Ïî
                    String address = Objects.requireNonNull(data.getExtras()).getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);  //»ñÈ¡ÁÐ±íÏîÖÐÉè±¸µÄmacµØÖ·
                    con_dev = mService.getDevByMac(address);
                    mService.connect(con_dev);
                }

                break;
        }
    }

    public static class Formatter {
        private byte[] mFormat;

        public Formatter() {
            // Default:
            mFormat = new byte[]{27, 33, 0};
        }

        /**
         * Method to get the Build result
         *
         * @return the format
         */
        public byte[] get() {
            return mFormat;
        }

        public Formatter bold() {
            // Apply bold:
            mFormat[2] = ((byte) (0x8 | mFormat[2]));
            return this;
        }

        public Formatter small() {
            mFormat[2] = ((byte) (0x1 | mFormat[2]));
            return this;
        }

        public Formatter height() {
            mFormat[2] = ((byte) (0x10 | mFormat[2]));
            return this;
        }

        public Formatter width() {
            mFormat[2] = ((byte) (0x20 | mFormat[2]));
            return this;
        }

        public Formatter underlined() {
            mFormat[2] = ((byte) (0x80 | mFormat[2]));
            return this;
        }

        public static byte[] rightAlign() {
            return new byte[]{0x1B, 'a', 0x02};
        }

        public static byte[] leftAlign() {
            return new byte[]{0x1B, 'a', 0x00};
        }

        public static byte[] centerAlign() {
            return new byte[]{0x1B, 'a', 0x01};
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == android.R.id.home) {
            overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
            PrinterActivity.this.finish();
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
        PrinterActivity.this.finish();
    }


    private static final int WHITE = 0xFFFFFFFF;
    private static final int BLACK = 0xFF000000;

    private static Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int img_width, int img_height) throws WriterException {
        if (contents == null) {
            return null;
        }
        Map<EncodeHintType, Object> hints = null;
        String encoding = guessAppropriateEncoding(contents);
        if (encoding != null) {
            hints = new EnumMap<>(EncodeHintType.class);
            hints.put(EncodeHintType.CHARACTER_SET, encoding);
        }
        MultiFormatWriter writer = new MultiFormatWriter();
        BitMatrix result;
        try {
            result = writer.encode(contents, format, img_width, img_height, hints);
        } catch (IllegalArgumentException iae) {
            // Unsupported format
            return null;
        }
        int width = result.getWidth();
        int height = result.getHeight();
        int[] pixels = new int[width * height];
        for (int y = 0; y < height; y++) {
            int offset = y * width;
            for (int x = 0; x < width; x++) {
                pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
            }
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }

    private static String guessAppropriateEncoding(CharSequence contents) {
        // Very crude at the moment
        for (int i = 0; i < contents.length(); i++) {
            if (contents.charAt(i) > 0xFF) {
                return "UTF-8";
            }
        }
        return null;
    }

    //print photo
    public void printPhoto(Bitmap bmp) {
        try {
            //Bitmap bmp = BitmapFactory.decodeResource(getResources(), img);
            if (bmp != null) {
                byte[] command = Utils.decodeBitmap(bmp);
                mService.write(PrinterCommands.ESC_ALIGN_CENTER);
                printText(command);
            } else {
                //test("Print Photo error", "the file isn't exists");
            }
        } catch (Exception e) {
            e.fillInStackTrace();
            //test("PrintTools", "the file isn't exists");
        }
    }

    //print byte[]
    private void printText(byte[] msg) {
        // Print normal text
        mService.write(msg);
        printNewLine();
    }

    //print new line
    private void printNewLine() {
        mService.write(PrinterCommands.FEED_LINE);

    }

    private void print_image(Bitmap bmp) {
        BitSet dots = new BitSet();
        mService.write(PrinterCommands.SET_LINE_SPACING_24);

        int offset = 0;
        while (offset < bmp.getHeight()) {
            mService.write(PrinterCommands.SELECT_BIT_IMAGE_MODE);
            for (int x = 0; x < bmp.getWidth(); ++x) {
                for (int k = 0; k < 3; ++k) {
                    byte slice = 0;
                    for (int b = 0; b < 8; ++b) {
                        int y = (((offset / 8) + k) * 8) + b;
                        int i = (y * bmp.getWidth()) + x;
                        boolean v = false;
                        if (i < dots.length()) {
                            v = dots.get(i);
                        }
                        slice |= (byte) ((v ? 1 : 0) << (7 - b));
                    }
                    mService.write(new byte[]{slice});
                }
            }

            offset += 24;
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
        }
        mService.write(PrinterCommands.SET_LINE_SPACING_30);
    }


    void requestBluetooth() {
        // Check if the Android version is 12 (S) or above
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            requestMultiplePermissions.launch(
                    new String[]{
                            Manifest.permission.BLUETOOTH_SCAN,
                            Manifest.permission.BLUETOOTH_CONNECT
                    }
            );
        } else {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            requestEnableBluetooth.launch(enableBtIntent);
        }
    }

    private final ActivityResultLauncher<Intent> requestEnableBluetooth = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    // Bluetooth enabling was granted
                    //test("MyTag", "Granted Bluetooth permission");
                } else {
                    // Bluetooth enabling was denied
                    //test("MyTag", "Denied Bluetooth permission");
                }
            }
    );

    private final ActivityResultLauncher<String[]> requestMultiplePermissions = registerForActivityResult(
            new ActivityResultContracts.RequestMultiplePermissions(),
            permissions -> {
                for (Map.Entry<String, Boolean> entry : permissions.entrySet()) {
                    //test("MyTag", entry.getKey() + " = " + entry.getValue());
                }
            }
    );
}


