package com.pdf417scanner;

import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import java.util.Map;

public class PDF417CameraViewManager extends SimpleViewManager<PDF417CameraView> 
    implements PDF417CameraView.CameraReadyListener, PDF417CameraView.ScanResultListener {
    
    public static final String REACT_CLASS = "PDF417CameraView";
    
    private PDF417CameraView currentCameraView;
    private PDF417ScannerModule scannerModule;

    public void setScannerModule(PDF417ScannerModule module) {
        this.scannerModule = module;
    }

    @NonNull
    @Override
    public String getName() {
        return REACT_CLASS;
    }

    @NonNull
    @Override
    protected PDF417CameraView createViewInstance(@NonNull ThemedReactContext reactContext) {
        PDF417CameraView cameraView = new PDF417CameraView(reactContext);
        cameraView.setCameraReadyListener(this);
        cameraView.setScanResultListener(this);
        currentCameraView = cameraView;
        return cameraView;
    }

    @ReactProp(name = "isActive")
    public void setIsActive(PDF417CameraView view, boolean isActive) {
        if (isActive) {
            view.startCamera();
        } else {
            view.stopCamera();
        }
    }

    @ReactProp(name = "isScanning")
    public void setIsScanning(PDF417CameraView view, boolean isScanning) {
        if (isScanning) {
            view.startScanning();
        } else {
            view.stopScanning();
        }
    }

    @ReactProp(name = "torchEnabled")
    public void setTorchEnabled(PDF417CameraView view, boolean torchEnabled) {
        view.setTorchEnabled(torchEnabled);
    }

    @ReactProp(name = "triggerFocus")
    public void setTriggerFocus(PDF417CameraView view, boolean trigger) {
        if (trigger) {
            view.triggerAutoFocus();
        }
    }

    @Override
    public void onDropViewInstance(@NonNull PDF417CameraView view) {
        view.stopCamera();
        super.onDropViewInstance(view);
    }

    @Nullable
    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
            .put("onCameraReady", MapBuilder.of("registrationName", "onCameraReady"))
            .put("onCameraError", MapBuilder.of("registrationName", "onCameraError"))
            .build();
    }

    // CameraReadyListener implementation
    @Override
    public void onCameraReady() {
        if (currentCameraView != null) {
            WritableMap event = Arguments.createMap();
            ReactContext reactContext = (ReactContext) currentCameraView.getContext();
            reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                currentCameraView.getId(),
                "onCameraReady",
                event);
        }
    }

    @Override
    public void onCameraError(String error) {
        if (currentCameraView != null) {
            WritableMap event = Arguments.createMap();
            event.putString("error", error);
            ReactContext reactContext = (ReactContext) currentCameraView.getContext();
            reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                currentCameraView.getId(),
                "onCameraError",
                event);
        }
    }

    // ScanResultListener implementation
    @Override
    public void onScanResult(String data, String format) {
        if (scannerModule != null) {
            scannerModule.onScanResult(data, format);
        }
    }

    @Override
    public void onScanError(String code, String message) {
        if (scannerModule != null) {
            scannerModule.onScanError(code, message);
        }
    }
}