package com.manasuka.pos;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Base64;
import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

@CapacitorPlugin(
    name = "BluetoothSerial",
    permissions = {
        @Permission(strings = { Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN }, alias = "bluetooth"),
        @Permission(strings = { "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_SCAN" }, alias = "bluetoothNew")
    }
)
public class BluetoothSerialPlugin extends Plugin {
    // Standard SerialPortProfile (SPP) UUID used by ESC/POS thermal receipt printers
    private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private BluetoothSocket socket = null;
    private OutputStream outputStream = null;

    @PluginMethod
    public void isEnabled(PluginCall call) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        JSObject ret = new JSObject();
        ret.put("enabled", adapter != null && adapter.isEnabled());
        call.resolve(ret);
    }

    @PluginMethod
    public void enable(PluginCall call) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null) {
            call.reject("Bluetooth tidak tersedia di perangkat ini");
            return;
        }
        JSObject ret = new JSObject();
        ret.put("enabled", adapter.isEnabled());
        call.resolve(ret);
    }

    @PluginMethod
    public void list(PluginCall call) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null) {
            call.reject("Bluetooth tidak tersedia di perangkat ini");
            return;
        }

        JSArray devicesList = new JSArray();
        try {
            Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
            if (pairedDevices != null) {
                for (BluetoothDevice device : pairedDevices) {
                    JSObject dev = new JSObject();
                    dev.put("name", device.getName() != null ? device.getName() : "Thermal Printer");
                    dev.put("address", device.getAddress());
                    dev.put("id", device.getAddress());
                    devicesList.put(dev);
                }
            }
        } catch (SecurityException e) {
            call.reject("Izin akses Bluetooth ditolak: " + e.getMessage());
            return;
        }

        JSObject ret = new JSObject();
        ret.put("devices", devicesList);
        call.resolve(ret);
    }

    @PluginMethod
    public void connect(PluginCall call) {
        String address = call.getString("address");
        if (address == null || address.isEmpty()) {
            call.reject("Alamat MAC printer tidak boleh kosong");
            return;
        }

        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null) {
            call.reject("Bluetooth tidak tersedia");
            return;
        }

        try {
            closeSocket();
            BluetoothDevice device = adapter.getRemoteDevice(address);
            socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
            socket.connect();
            outputStream = socket.getOutputStream();

            JSObject ret = new JSObject();
            ret.put("success", true);
            ret.put("address", address);
            call.resolve(ret);
        } catch (Exception e) {
            closeSocket();
            call.reject("Gagal menghubungkan ke printer Bluetooth: " + e.getMessage());
        }
    }

    @PluginMethod
    public void disconnect(PluginCall call) {
        closeSocket();
        JSObject ret = new JSObject();
        ret.put("success", true);
        call.resolve(ret);
    }

    @PluginMethod
    public void write(PluginCall call) {
        String base64Value = call.getString("value");
        if (base64Value == null) {
            call.reject("Data cetak kosong");
            return;
        }

        if (socket == null || !socket.isConnected() || outputStream == null) {
            call.reject("Printer Bluetooth tidak terhubung");
            return;
        }

        try {
            byte[] bytes = Base64.decode(base64Value, Base64.DEFAULT);
            outputStream.write(bytes);
            outputStream.flush();

            JSObject ret = new JSObject();
            ret.put("success", true);
            call.resolve(ret);
        } catch (Exception e) {
            closeSocket();
            call.reject("Gagal mengirim bytes ke printer: " + e.getMessage());
        }
    }

    private void closeSocket() {
        if (outputStream != null) {
            try { outputStream.close(); } catch (Exception ignored) {}
            outputStream = null;
        }
        if (socket != null) {
            try { socket.close(); } catch (Exception ignored) {}
            socket = null;
        }
    }

    @Override
    protected void handleOnDestroy() {
        closeSocket();
        super.handleOnDestroy();
    }
}
