// RockChipInterface.java
package io.kiotplugins.rockchipinterface;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class RockChipInterface extends CordovaPlugin {
    private static final String TAG = "RockChipInterface";
    
    // Action constants
    private static final String ACTION_START = "start";
    private static final String ACTION_STOP = "stop";
    private static final String ACTION_GET_POSITION = "getPosition";
    private static final String ACTION_SET_POSITION = "setPosition";
    
    // Event type constants
    private static final int EVENT_TYPE_ROTATION = 1;
    private static final int EVENT_TYPE_BUTTON = 2;
    
    // Known input codes
    private static final int CODE_ROTATION_CLOCKWISE = 0x0040;
    private static final int CODE_ROTATION_COUNTER_CLOCKWISE = 0x0041;
    private static final int CODE_BUTTON_MIDDLE = 0x003f;
    
    // Callback context for events
    private CallbackContext eventCallback;
    
    // Flag to track if the native reader is running
    private boolean isRunning = false;
    
    // Load the native library
    static {
        System.loadLibrary("rockchipinterface");
    }
    
    // Native method declarations
    private native boolean initializeNative();
    private native void shutdownNative();
    private native int getRotaryPositionNative();
    private native void setRotaryPositionNative(int position);
    
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        try {
            if (ACTION_START.equals(action)) {
                return startInterface(callbackContext);
            } else if (ACTION_STOP.equals(action)) {
                return stopInterface(callbackContext);
            } else if (ACTION_GET_POSITION.equals(action)) {
                return getPosition(callbackContext);
            } else if (ACTION_SET_POSITION.equals(action)) {
                return setPosition(args, callbackContext);
            }
            
            callbackContext.error("Invalid action: " + action);
            return false;
        } catch (Exception e) {
            callbackContext.error("Exception: " + e.getMessage());
            return false;
        }
    }
    
    private boolean startInterface(CallbackContext callbackContext) {
        if (isRunning) {
            callbackContext.error("Interface is already running");
            return false;
        }
        
        // Store callback context
        this.eventCallback = callbackContext;
        
        // Initialize the native interface
        if (!initializeNative()) {
            callbackContext.error("Failed to initialize native interface");
            return false;
        }
        
        isRunning = true;
        
        // Return success but keep the callback
        PluginResult result = new PluginResult(PluginResult.Status.OK, "Interface started");
        result.setKeepCallback(true);
        callbackContext.sendPluginResult(result);
        
        return true;
    }
    
    private boolean stopInterface(CallbackContext callbackContext) {
        if (!isRunning) {
            callbackContext.error("Interface is not running");
            return false;
        }
        
        // Shutdown the native interface
        shutdownNative();
        isRunning = false;
        
        // Clear callback
        if (eventCallback != null) {
            eventCallback.success("Interface stopped");
            eventCallback = null;
        }
        
        callbackContext.success("Interface stopped");
        return true;
    }
    
    private boolean getPosition(CallbackContext callbackContext) {
        if (!isRunning) {
            callbackContext.error("Interface is not running");
            return false;
        }
        
        int position = getRotaryPositionNative();
        callbackContext.success(position);
        return true;
    }
    
    private boolean setPosition(JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (!isRunning) {
            callbackContext.error("Interface is not running");
            return false;
        }
        
        if (args.length() < 1) {
            callbackContext.error("Missing position parameter");
            return false;
        }
        
        int position = args.getInt(0);
        setRotaryPositionNative(position);
        callbackContext.success("Position set to " + position);
        return true;
    }
    
    // Callback method called from native code
    public void notifyInputEvent(int eventType, int eventCode, int eventValue) {
        if (eventCallback != null) {
            try {
                JSONObject event = new JSONObject();
                
                if (eventType == EVENT_TYPE_ROTATION) {
                    event.put("type", "rotation");
                    if (eventCode == CODE_ROTATION_CLOCKWISE) {
                        event.put("direction", "clockwise");
                    } else if (eventCode == CODE_ROTATION_COUNTER_CLOCKWISE) {
                        event.put("direction", "counterclockwise");
                    }
                    event.put("code", eventCode);
                    event.put("position", eventValue);
                } else if (eventType == EVENT_TYPE_BUTTON) {
                    event.put("type", "button");
                    event.put("code", eventCode);
                    event.put("action", eventValue == 1 ? "press" : "release");
                    
                    // Map known button codes to names
                    if (eventCode == CODE_BUTTON_MIDDLE) {
                        event.put("name", "middle");
                    } else {
                        event.put("name", "unknown");
                    }
                }
                
                PluginResult result = new PluginResult(PluginResult.Status.OK, event);
                result.setKeepCallback(true);
                eventCallback.sendPluginResult(result);
            } catch (JSONException e) {
                // Ignore
            }
        }
    }
    
    @Override
    public void onDestroy() {
        if (isRunning) {
            shutdownNative();
            isRunning = false;
        }
        super.onDestroy();
    }
}