package com.bebekmbareina.pos;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Base64;
import androidx.core.content.ContextCompat;

import com.getcapacitor.JSObject;
import com.getcapacitor.PermissionState;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import com.getcapacitor.annotation.PermissionCallback;

import org.json.JSONArray;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

@CapacitorPlugin(
    name = "BluetoothPrinter",
    permissions = {
        @Permission(
            alias = "bluetooth",
            strings = {
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.BLUETOOTH_SCAN
            }
        )
    }
)
public class BluetoothPrinterPlugin extends Plugin {

    private BluetoothAdapter bluetoothAdapter;
    private BluetoothSocket bluetoothSocket;
    private OutputStream outputStream;
    // Standard SerialPortService ID
    private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    @Override
    public void load() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    @PluginMethod
    public void getPairedDevices(PluginCall call) {
        if (bluetoothAdapter == null) {
            call.reject("Bluetooth tidak didukung di perangkat ini");
            return;
        }

        if (!bluetoothAdapter.isEnabled()) {
            call.reject("Bluetooth sedang tidak aktif");
            return;
        }

        // Runtime permission check for Android 12+ (API 31+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                requestPermissionForAlias("bluetooth", call, "bluetoothPermissionCallback");
                return;
            }
        }

        try {
            Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
            JSONArray devices = new JSONArray();

            if (pairedDevices != null && pairedDevices.size() > 0) {
                for (BluetoothDevice device : pairedDevices) {
                    try {
                        JSObject dev = new JSObject();
                        dev.put("name", device.getName());
                        dev.put("address", device.getAddress());
                        devices.put(dev);
                    } catch (Exception e) {}
                }
            }

            JSObject ret = new JSObject();
            ret.put("devices", devices);
            call.resolve(ret);
        } catch (SecurityException se) {
            call.reject("Gagal mengakses Bluetooth: Izin tidak diberikan. Detail: " + se.getMessage());
        } catch (Exception e) {
            call.reject("Gagal mendapatkan perangkat bluetooth: " + e.getMessage());
        }
    }

    @PluginMethod
    public void printReceipt(PluginCall call) {
        String macAddress = call.getString("macAddress");
        String dataBase64 = call.getString("dataBase64");

        if (macAddress == null || dataBase64 == null) {
            call.reject("macAddress dan dataBase64 diperlukan");
            return;
        }

        // Runtime permission check for Android 12+ (API 31+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                requestPermissionForAlias("bluetooth", call, "bluetoothPermissionCallbackPrint");
                return;
            }
        }

        try {
            BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAddress);
            bluetoothSocket = device.createRfcommSocketToServiceRecord(SPP_UUID);
            bluetoothSocket.connect();
            outputStream = bluetoothSocket.getOutputStream();

            byte[] decodedBytes = Base64.decode(dataBase64, Base64.DEFAULT);
            outputStream.write(decodedBytes);
            outputStream.flush();
            
            // Allow buffer to empty
            Thread.sleep(1000);
            
            bluetoothSocket.close();
            
            call.resolve(new JSObject().put("success", true));
        } catch (SecurityException se) {
            call.reject("Gagal mencetak: Izin Bluetooth tidak diberikan. Detail: " + se.getMessage());
        } catch (Exception e) {
            try {
                if (bluetoothSocket != null) bluetoothSocket.close();
            } catch (Exception ex) {}
            call.reject("Gagal terhubung ke printer: " + e.getMessage());
        }
    }

    @PermissionCallback
    public void bluetoothPermissionCallback(PluginCall call) {
        if (getPermissionState("bluetooth") == PermissionState.GRANTED) {
            getPairedDevices(call);
        } else {
            call.reject("Izin akses Bluetooth Connect diperlukan untuk mendeteksi printer thermal.");
        }
    }

    @PermissionCallback
    public void bluetoothPermissionCallbackPrint(PluginCall call) {
        if (getPermissionState("bluetooth") == PermissionState.GRANTED) {
            printReceipt(call);
        } else {
            call.reject("Izin akses Bluetooth Connect diperlukan untuk mencetak struk.");
        }
    }
}
