package com.innov8tif.okaycam;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Size;
import android.util.Log;

import com.caverock.androidsvg.PreserveAspectRatio;
import com.caverock.androidsvg.RenderOptions;
import com.caverock.androidsvg.SVG;
import com.caverock.androidsvg.SVGParseException;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;

import com.innov8tif.okaycam.cam.OkayCamAutoDoc;
import com.innov8tif.okaycam.config.CameraFacing;
import com.innov8tif.okaycam.config.OkayCamBtnConfig;
import com.innov8tif.okaycam.config.OkayCamAutoCaptureConfig;
import com.innov8tif.okaycam.config.OkayCamAutoCaptureMode;
import com.innov8tif.okaycam.config.OkaySelfieConfig;
import com.innov8tif.okaycam.config.OkaySelfieLabelConfig;
import com.innov8tif.okaycam.config.OkaySelfieSwichBtnConfig;
import com.innov8tif.okaycam.selfie.OkayCamSelfie;
import com.innov8tif.okaycam.selfie.OkaySelfiePlus;
import com.innov8tif.okaycam.utils.BitmapUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class RNOkayCamPlusModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;

    public RNOkayCamPlusModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public String getName() {
        return "RNOkayCamPlus";
    }

    @ReactMethod
    public void captureDocument(ReadableMap configs, Promise promise) {
        String LICENSE_KEY = configs.getString("license");

        Boolean base64 = configs.getBoolean("base64");
        ReadableMap userConfig = configs.getMap("config");
        OkayCamAutoCaptureConfig config = OkayCamAutoCaptureConfig.init();

        Log.d("OkayCam", "userConfig: " + userConfig.toString());

        if (userConfig.hasKey("width") && !userConfig.isNull("width")) {
            int width = userConfig.getInt("width");
            if (width != -1) {
                config.setWidth(width);
            }
        }

        if (userConfig.hasKey("imageQuality") && !userConfig.isNull("imageQuality")) {
            double quality = userConfig.getDouble("imageQuality");
            if (quality > 0.0) {
                config.setImageQuality((float) quality);
            }
        }

        if (userConfig.hasKey("autoCapture") && !userConfig.isNull("autoCapture")) {
            config.setAutoCapture(userConfig.getBoolean("autoCapture"));
        }

        config.setMode(parseMode(userConfig.getString("mode")));

        OkayCamAutoDoc.start(this.getCurrentActivity(), LICENSE_KEY, config, (success, images, exception) -> {
            if (success) {
                JSONObject results = new JSONObject();
                try {
                    results.put("fullDocumentImage", base64 ? convertImgToBase64(base64, images.get(0)) : images.get(0));

                    if (images.size() > 1) {
                        results.put("fullDocumentImage2", base64 ? convertImgToBase64(base64, images.get(1)) : images.get(1));
                    }

                    if (images.size() > 2) {
                        results.put("fullDocumentImage3", base64 ? convertImgToBase64(base64, images.get(2)) : images.get(2));
                    }

                    if (images.size() > 3) {
                        results.put("fullDocumentImage4", base64 ? convertImgToBase64(base64, images.get(3)) : images.get(3));
                    }

                    promise.resolve(results.toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                    promise.reject(this.getError(e.getMessage()));
                }
            } else {
                promise.reject(this.getError(exception.getMessage()));
            }
            return null;
        });
    }

    @ReactMethod
    public void captureSelfie(ReadableMap configs, Promise promise) {
        String LICENSE_KEY = configs.getString("license");

        Boolean base64 = configs.getBoolean("base64");

        ReadableMap userConfig = configs.getMap("config");
        ReadableMap topLabel = userConfig.getMap("topLabel");
        ReadableMap switchBtnConfig = userConfig.getMap("switchBtnConfig");
        ReadableMap confirmBtnConfig = userConfig.getMap("confirmBtnConfig");
        ReadableMap retakeBtnConfig = userConfig.getMap("retakeBtnConfig");

        OkaySelfieConfig okaySelfieConfig = OkaySelfieConfig.init(this.getCurrentActivity());

        okaySelfieConfig.setTopLabel(new OkaySelfieLabelConfig(
                topLabel.getString("text"),
                Color.parseColor(topLabel.getString("color")),
                topLabel.getInt("size")
        ));
        okaySelfieConfig.setBottomFrameColor(Color.parseColor(userConfig.getString("bottomFrameColor")));

        okaySelfieConfig.setCaptureBtnColor(Color.parseColor(userConfig.getString("captureBtnColor")));

        okaySelfieConfig.setSwitchBtnConfig(new OkaySelfieSwichBtnConfig(
                Color.parseColor(switchBtnConfig.getString("color")),
                switchBtnConfig.getBoolean("show")
        ));

        okaySelfieConfig.setConfirmBtnConfig(new OkayCamBtnConfig(
                Color.parseColor(confirmBtnConfig.getString("backgroundColor")),
                Color.parseColor(confirmBtnConfig.getString("contentColor"))
        ));

        okaySelfieConfig.setRetakeBtnConfig(new OkayCamBtnConfig(
                Color.parseColor(retakeBtnConfig.getString("backgroundColor")),
                Color.parseColor(retakeBtnConfig.getString("contentColor"))
        ));

        if (userConfig.getString("defaultCameraFacing").equals("front")) {
            okaySelfieConfig.setDefaultCameraFacing(CameraFacing.FRONT);
        } else if (userConfig.getString("defaultCameraFacing").equals("back")) {
            okaySelfieConfig.setDefaultCameraFacing(CameraFacing.BACK);
        }

        if (userConfig.getInt("width") != -1) {
            okaySelfieConfig.setWidth(userConfig.getInt("width"));
        }

        okaySelfieConfig.setImageQuality((float) userConfig.getDouble("imageQuality"));

        OkayCamSelfie.start(this.getCurrentActivity(), LICENSE_KEY, okaySelfieConfig, (success, image, exception) -> {
            if (success) {
                JSONObject results = new JSONObject();
                try {
                    results.put("selfieImage", base64 ? convertImgToBase64(base64, image) : image);
                    promise.resolve(results.toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                    promise.reject(this.getError(e.getMessage()));
                }
            } else {
                promise.reject(this.getError(exception.getMessage()));
            }
            return null;
        });
    }

    @ReactMethod
    public void captureSelfiePlus(ReadableMap configs, Promise promise) {
        String LICENSE_KEY = configs.getString("license");

        Boolean base64 = configs.getBoolean("base64");

        OkaySelfiePlus.start(this.getCurrentActivity(), LICENSE_KEY, (success, result, exception) -> {
            if (success) {
                try {
                    if (result == null) {
                        promise.reject(this.getError("Result is null"));
                        return null;
                    }

                    // Log compactly
                    Log.d("OkaySelfiePlus", "Raw result: " + result);

                    JSONObject results = new JSONObject(result);
                    Log.d("OkaySelfiePlus", "Parsed results: " + results);

                    // Convert selfie image if base64 is requested
                    if (results.has("selfie")) {
                        String selfie = results.optString("selfie");
                        if (base64) {
                            selfie = convertImgToBase64(true, selfie);
                            results.put("selfie", selfie);
                        }
                    }

                    Log.d("OkaySelfiePlus", "Final results: " + results);
                    promise.resolve(results.toString());
                } catch (Exception e) {
                    Log.e("OkaySelfiePlus", "Error parsing results", e);
                    promise.reject(this.getError(e.getMessage()));
                }
            } else {
                Log.e("OkaySelfiePlus", "Operation failed", exception);
                promise.reject(this.getError(exception.getMessage()));
            }
            return null;
        });
    }

    public String convertImgToBase64(Boolean base64, String image) {
        String result = "file://" + image;

        if (base64) {
            result = BitmapUtils.INSTANCE.convertToBase64(image);
        }

        return result;
    }

    private Exception getError(String error) {
        String errorString = "";
        switch (error) {
            case "Invalid license key":
                errorString = "invalid license";
                break;
            case "User refused to grant permission.":
                errorString = "camera permission denied";
                break;
            case "User cancelled the activity.":
                errorString = "cancel";
                break;
            default:
                errorString = "failed";
        }
        return new Exception(errorString);
    }

    private OkayCamAutoCaptureMode parseMode(String mode) {
        if (mode == null) return OkayCamAutoCaptureMode.FULL;

        switch (mode) {
            case "FRONT_ONLY":
                return OkayCamAutoCaptureMode.FRONT_ONLY;
            case "FRONT_BACK":
                return OkayCamAutoCaptureMode.FRONT_BACK;
            case "FRONT_WITH_FLASH":
                return OkayCamAutoCaptureMode.FRONT_WITH_FLASH;
            default:
                return OkayCamAutoCaptureMode.FULL;
        }
    }
}
