package com.example.bdkipoc.transaction.managers;

import android.os.RemoteException;
import android.util.Log;

import com.example.bdkipoc.MyApplication;
import com.example.bdkipoc.utils.ByteUtil;
import com.sunmi.pay.hardware.aidlv2.AidlErrorCodeV2;
import com.sunmi.pay.hardware.aidlv2.bean.PinPadConfigV2;
import com.sunmi.pay.hardware.aidlv2.pinpad.PinPadListenerV2;
import com.sunmi.pay.hardware.aidlv2.pinpad.PinPadOptV2;

/**
 * PinPadManager - Handles PIN pad operations
 */
public class PinPadManager {
    private static final String TAG = "PinPadManager";
    
    private PinPadOptV2 mPinPadOptV2;
    private PinPadManagerCallback callback;
    
    public interface PinPadManagerCallback {
        void onPinInputLength(int length);
        void onPinInputConfirmed(byte[] pinBlock);
        void onPinInputCancelled();
        void onPinInputError(int code, String message);
    }
    
    public PinPadManager(PinPadManagerCallback callback) {
        this.callback = callback;
        initPinPadComponents();
    }
    
    private void initPinPadComponents() {
        if (MyApplication.app != null) {
            mPinPadOptV2 = MyApplication.app.pinPadOptV2;
            Log.d(TAG, "PIN Pad components initialized");
        } else {
            Log.e(TAG, "MyApplication.app is null");
        }
    }
    
    public void initPinPad(String cardNo, int pinType) {
        Log.d(TAG, "========== PIN PAD INITIALIZATION ==========");
        try {
            if (mPinPadOptV2 == null) {
                throw new IllegalStateException("PIN Pad service not available");
            }

            if (cardNo == null || cardNo.length() < 13) {
                throw new IllegalArgumentException("Invalid card number for PIN");
            }

            PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
            pinPadConfig.setPinPadType(0);
            pinPadConfig.setPinType(pinType);
            pinPadConfig.setOrderNumKey(true);  // Set to true for normal order, false for random
            
            String panForPin = cardNo.substring(cardNo.length() - 13, cardNo.length() - 1);
            byte[] panBytes = panForPin.getBytes("US-ASCII");
            pinPadConfig.setPan(panBytes);
            
            pinPadConfig.setTimeout(60 * 1000);
            pinPadConfig.setPinKeyIndex(12);
            pinPadConfig.setMaxInput(12);
            pinPadConfig.setMinInput(0);
            pinPadConfig.setKeySystem(0);
            pinPadConfig.setAlgorithmType(0);
            
            Log.d(TAG, "Initializing PIN pad with config");
            mPinPadOptV2.initPinPad(pinPadConfig, mPinPadListener);
            
        } catch (Exception e) {
            Log.e(TAG, "PIN pad initialization failed: " + e.getMessage());
            if (callback != null) {
                callback.onPinInputError(-1, "PIN Error: " + e.getMessage());
            }
        }
    }
    
    public void cancelPinInput() {
        try {
            if (mPinPadOptV2 != null) {
                // Cancel PIN input if needed
                Log.d(TAG, "PIN input cancelled");
            }
        } catch (Exception e) {
            Log.e(TAG, "Error cancelling PIN input: " + e.getMessage());
        }
    }
    
    // PIN Pad Listener
    private final PinPadListenerV2 mPinPadListener = new PinPadListenerV2.Stub() {
        @Override
        public void onPinLength(int len) throws RemoteException {
            Log.d(TAG, "PIN input length: " + len);
            if (callback != null) {
                callback.onPinInputLength(len);
            }
        }

        @Override
        public void onConfirm(int i, byte[] pinBlock) throws RemoteException {
            Log.d(TAG, "PIN input confirmed");
            
            if (pinBlock != null) {
                String hexStr = ByteUtil.bytes2HexStr(pinBlock);
                Log.d(TAG, "PIN block received: " + hexStr);
                if (callback != null) {
                    callback.onPinInputConfirmed(pinBlock);
                }
            } else {
                Log.d(TAG, "PIN bypass confirmed");
                if (callback != null) {
                    callback.onPinInputConfirmed(null);
                }
            }
        }

        @Override
        public void onCancel() throws RemoteException {
            Log.d(TAG, "PIN input cancelled by user");
            if (callback != null) {
                callback.onPinInputCancelled();
            }
        }

        @Override
        public void onError(int code) throws RemoteException {
            Log.e(TAG, "PIN pad error: " + code);
            String msg = AidlErrorCodeV2.valueOf(code).getMsg();
            if (callback != null) {
                callback.onPinInputError(code, msg);
            }
        }

        @Override
        public void onHover(int event, byte[] data) throws RemoteException {
            Log.d(TAG, "PIN pad hover event: " + event);
        }
    };
}