package ee.forgr.capacitor_inappbrowser;

import android.content.res.AssetManager;
import androidx.annotation.Nullable;
import com.getcapacitor.JSObject;
import com.getcapacitor.PluginCall;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.regex.Pattern;

public class Options {

    public enum InvisibilityMode {
        AWARE,
        FAKE_VISIBLE;

        public static InvisibilityMode fromString(String value) {
            if (value == null) {
                return AWARE;
            }

            try {
                return InvisibilityMode.valueOf(value.trim().toUpperCase());
            } catch (IllegalArgumentException e) {
                return AWARE;
            }
        }
    }

    public static class ButtonNearDone {

        public enum AllIconTypes {
            ASSET,
            VECTOR
        }

        private final AllIconTypes iconTypeEnum;
        private final String iconType;
        private final String icon;
        private final int height;
        private final int width;

        private ButtonNearDone(AllIconTypes iconTypeEnum, String iconType, String icon, int height, int width) {
            this.iconTypeEnum = iconTypeEnum;
            this.iconType = iconType;
            this.icon = icon;
            this.height = height;
            this.width = width;
        }

        @Nullable
        public static ButtonNearDone generateFromPluginCall(PluginCall call, AssetManager assetManager)
            throws IllegalArgumentException, RuntimeException {
            JSObject buttonNearDone = call.getObject("buttonNearDone");
            if (buttonNearDone == null) {
                // Return null when "buttonNearDone" isn't configured, else throw an error
                return null;
            }

            JSObject android = buttonNearDone.getJSObject("android");
            if (android == null) {
                throw new IllegalArgumentException("buttonNearDone.android is null");
            }

            String iconType = android.getString("iconType", "asset");
            AllIconTypes iconTypeEnum;

            // Validate and process icon type
            if ("asset".equals(iconType)) {
                iconTypeEnum = AllIconTypes.ASSET;
            } else if ("vector".equals(iconType)) {
                iconTypeEnum = AllIconTypes.VECTOR;
            } else {
                throw new IllegalArgumentException("buttonNearDone.android.iconType must be 'asset' or 'vector'");
            }

            String icon = android.getString("icon");
            if (icon == null) {
                throw new IllegalArgumentException("buttonNearDone.android.icon is null");
            }

            // For asset type, verify the file exists
            if (iconTypeEnum == AllIconTypes.ASSET) {
                InputStream fileInputString = null;

                try {
                    // Try to find in public folder first
                    try {
                        fileInputString = assetManager.open("public/" + icon);
                    } catch (IOException e) {
                        // If not in public, try in root assets
                        try {
                            fileInputString = assetManager.open(icon);
                        } catch (IOException e2) {
                            throw new IllegalArgumentException("buttonNearDone.android.icon cannot be found in the assetManager");
                        }
                    }
                    // File exists, do nothing
                } finally {
                    // Close the input stream if it was opened
                    if (fileInputString != null) {
                        try {
                            fileInputString.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            // For vector type, we don't validate here since resources are checked at runtime
            else if (iconTypeEnum == AllIconTypes.VECTOR) {
                // Vector resources will be validated when used
                System.out.println("Vector resource will be validated at runtime: " + icon);
            }

            Integer width = android.getInteger("width", 24);
            Integer height = android.getInteger("height", 24);

            final ButtonNearDone buttonNearDone1 = new ButtonNearDone(iconTypeEnum, iconType, icon, height, width);
            return buttonNearDone1;
        }

        public AllIconTypes getIconTypeEnum() {
            return iconTypeEnum;
        }

        public String getIconType() {
            return iconType;
        }

        public String getIcon() {
            return icon;
        }

        public int getHeight() {
            return height;
        }

        public int getWidth() {
            return width;
        }
    }

    private String title;
    private boolean CloseModal;
    private String CloseModalTitle;
    private String CloseModalDescription;
    private String CloseModalCancel;
    private ButtonNearDone buttonNearDone;
    private String CloseModalOk;
    private Pattern closeModalURLPattern;
    private String url;
    private JSObject headers;
    private JSObject credentials;
    private String toolbarType;
    private JSObject shareDisclaimer;
    private String shareSubject;
    private boolean disableGoBackOnNativeApplication;
    private boolean activeNativeNavigationForWebview;
    private boolean isPresentAfterPageLoad;
    private WebViewCallbacks callbacks;
    private PluginCall pluginCall;
    private boolean VisibleTitle;
    private String ToolbarColor;
    private String BackgroundColor;
    private boolean ShowArrow;
    private boolean ignoreUntrustedSSLError;
    private String preShowScript;
    private String toolbarTextColor;
    private Pattern proxyRequestsPattern = null;
    private boolean proxyRequests = false;
    private List<NativeProxyRule> outboundProxyRules = new ArrayList<>();
    private List<NativeProxyRule> inboundProxyRules = new ArrayList<>();
    private boolean materialPicker = false;
    private int textZoom = 100; // Default text zoom is 100%
    private boolean preventDeeplink = false;
    private boolean openBlankTargetInWebView = false;
    private List<String> authorizedAppLinks = new ArrayList<>();
    private boolean enabledSafeBottomMargin = false;
    private boolean enabledSafeTopMargin = true;
    private boolean useTopInset = false;
    private boolean enableGooglePaySupport = false;
    private boolean enableZoom = false;
    private List<String> blockedHosts = new ArrayList<>();
    private Integer width = null;
    private Integer height = null;
    private Integer x = null;
    private Integer y = null;
    private boolean hidden = false;
    private boolean showScreenshotButton = false;
    private boolean allowWebViewJsVisibilityControl = false;
    private boolean allowScreenshotsFromWebPage = false;
    private boolean captureConsoleLogs = false;
    private boolean handleDownloads = false;
    private InvisibilityMode invisibilityMode = InvisibilityMode.AWARE;
    private String httpMethod = null;
    private String httpBody = null;
    private boolean popupWindowMode = false;
    private boolean hiddenPopupWindow = false;

    public Integer getWidth() {
        return width;
    }

    public void setWidth(Integer width) {
        this.width = width;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public Integer getX() {
        return x;
    }

    public void setX(Integer x) {
        this.x = x;
    }

    public Integer getY() {
        return y;
    }

    public void setY(Integer y) {
        this.y = y;
    }

    public int getTextZoom() {
        return textZoom;
    }

    public void setTextZoom(int textZoom) {
        this.textZoom = textZoom;
    }

    public boolean getMaterialPicker() {
        return materialPicker;
    }

    public boolean getShowScreenshotButton() {
        return showScreenshotButton;
    }

    public void setShowScreenshotButton(boolean showScreenshotButton) {
        this.showScreenshotButton = showScreenshotButton;
    }

    public boolean getAllowScreenshotsFromWebPage() {
        return allowScreenshotsFromWebPage;
    }

    public void setAllowScreenshotsFromWebPage(boolean allowScreenshotsFromWebPage) {
        this.allowScreenshotsFromWebPage = allowScreenshotsFromWebPage;
    }

    public boolean getCaptureConsoleLogs() {
        return captureConsoleLogs;
    }

    public void setCaptureConsoleLogs(boolean captureConsoleLogs) {
        this.captureConsoleLogs = captureConsoleLogs;
    }

    public boolean getHandleDownloads() {
        return handleDownloads;
    }

    public void setHandleDownloads(boolean handleDownloads) {
        this.handleDownloads = handleDownloads;
    }

    public void setMaterialPicker(boolean materialPicker) {
        this.materialPicker = materialPicker;
    }

    public boolean getEnabledSafeMargin() {
        return enabledSafeBottomMargin;
    }

    public void setEnabledSafeMargin(boolean enabledSafeBottomMargin) {
        this.enabledSafeBottomMargin = enabledSafeBottomMargin;
    }

    public boolean getEnabledSafeTopMargin() {
        return enabledSafeTopMargin;
    }

    public void setEnabledSafeTopMargin(boolean enabledSafeTopMargin) {
        this.enabledSafeTopMargin = enabledSafeTopMargin;
    }

    public boolean getUseTopInset() {
        return useTopInset;
    }

    public void setUseTopInset(boolean useTopInset) {
        this.useTopInset = useTopInset;
    }

    public Pattern getProxyRequestsPattern() {
        return proxyRequestsPattern;
    }

    public void setProxyRequestsPattern(Pattern proxyRequestsPattern) {
        this.proxyRequestsPattern = proxyRequestsPattern;
    }

    public boolean getProxyRequests() {
        return proxyRequests;
    }

    public void setProxyRequests(boolean proxyRequests) {
        this.proxyRequests = proxyRequests;
    }

    public List<NativeProxyRule> getOutboundProxyRules() {
        return outboundProxyRules;
    }

    public void setOutboundProxyRules(List<NativeProxyRule> outboundProxyRules) {
        this.outboundProxyRules = outboundProxyRules != null ? outboundProxyRules : new ArrayList<>();
    }

    public List<NativeProxyRule> getInboundProxyRules() {
        return inboundProxyRules;
    }

    public void setInboundProxyRules(List<NativeProxyRule> inboundProxyRules) {
        this.inboundProxyRules = inboundProxyRules != null ? inboundProxyRules : new ArrayList<>();
    }

    public boolean shouldEnableNativeProxy() {
        return proxyRequests || proxyRequestsPattern != null || !outboundProxyRules.isEmpty() || !inboundProxyRules.isEmpty();
    }

    public PluginCall getPluginCall() {
        return pluginCall;
    }

    public void setPluginCall(PluginCall pluginCall) {
        this.pluginCall = pluginCall;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean getCloseModal() {
        return CloseModal;
    }

    public void setCloseModal(boolean CloseModal) {
        this.CloseModal = CloseModal;
    }

    public String getCloseModalTitle() {
        return CloseModalTitle;
    }

    public void setCloseModalTitle(String CloseModalTitle) {
        this.CloseModalTitle = CloseModalTitle;
    }

    public String getCloseModalDescription() {
        return CloseModalDescription;
    }

    public void setCloseModalDescription(String CloseModalDescription) {
        this.CloseModalDescription = CloseModalDescription;
    }

    public void setButtonNearDone(ButtonNearDone buttonNearDone) {
        this.buttonNearDone = buttonNearDone;
    }

    public ButtonNearDone getButtonNearDone() {
        return this.buttonNearDone;
    }

    public String getCloseModalCancel() {
        return CloseModalCancel;
    }

    public void setCloseModalCancel(String CloseModalCancel) {
        this.CloseModalCancel = CloseModalCancel;
    }

    public String getCloseModalOk() {
        return CloseModalOk;
    }

    public void setCloseModalOk(String CloseModalOk) {
        this.CloseModalOk = CloseModalOk;
    }

    public Pattern getCloseModalURLPattern() {
        return closeModalURLPattern;
    }

    public void setCloseModalURLPattern(Pattern closeModalURLPattern) {
        this.closeModalURLPattern = closeModalURLPattern;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public JSObject getHeaders() {
        return headers;
    }

    public void setHeaders(JSObject headers) {
        this.headers = headers;
    }

    public JSObject getCredentials() {
        return credentials;
    }

    public void setCredentials(JSObject credentials) {
        this.credentials = credentials;
    }

    public String getToolbarType() {
        return toolbarType;
    }

    public void setToolbarType(String toolbarType) {
        this.toolbarType = toolbarType;
    }

    public JSObject getShareDisclaimer() {
        return shareDisclaimer;
    }

    public boolean showReloadButton;

    public boolean getShowReloadButton() {
        return showReloadButton;
    }

    public void setShowReloadButton(boolean showReloadButton) {
        this.showReloadButton = showReloadButton;
    }

    public void setShareDisclaimer(JSObject shareDisclaimer) {
        this.shareDisclaimer = shareDisclaimer;
    }

    public String getShareSubject() {
        return shareSubject;
    }

    public void setShareSubject(String shareSubject) {
        this.shareSubject = shareSubject;
    }

    public boolean getActiveNativeNavigationForWebview() {
        return activeNativeNavigationForWebview;
    }

    public void setActiveNativeNavigationForWebview(boolean activeNativeNavigationForWebview) {
        this.activeNativeNavigationForWebview = activeNativeNavigationForWebview;
    }

    public boolean getDisableGoBackOnNativeApplication() {
        return disableGoBackOnNativeApplication;
    }

    public void setDisableGoBackOnNativeApplication(boolean disableGoBackOnNativeApplication) {
        this.disableGoBackOnNativeApplication = disableGoBackOnNativeApplication;
    }

    public boolean isPresentAfterPageLoad() {
        return isPresentAfterPageLoad;
    }

    public void setPresentAfterPageLoad(boolean presentAfterPageLoad) {
        isPresentAfterPageLoad = presentAfterPageLoad;
    }

    public WebViewCallbacks getCallbacks() {
        return callbacks;
    }

    public void setCallbacks(WebViewCallbacks callbacks) {
        this.callbacks = callbacks;
    }

    public boolean getVisibleTitle() {
        return VisibleTitle;
    }

    public void setVisibleTitle(boolean _visibleTitle) {
        this.VisibleTitle = _visibleTitle;
    }

    public String getToolbarColor() {
        return ToolbarColor;
    }

    public void setToolbarColor(String toolbarColor) {
        this.ToolbarColor = toolbarColor;
    }

    public String getBackgroundColor() {
        return BackgroundColor;
    }

    public void setBackgroundColor(String backgroundColor) {
        this.BackgroundColor = backgroundColor;
    }

    public String getToolbarTextColor() {
        return toolbarTextColor;
    }

    public void setToolbarTextColor(String toolbarTextColor) {
        this.toolbarTextColor = toolbarTextColor;
    }

    public boolean showArrow() {
        return ShowArrow;
    }

    public void setArrow(boolean _showArrow) {
        this.ShowArrow = _showArrow;
    }

    public boolean ignoreUntrustedSSLError() {
        return ignoreUntrustedSSLError;
    }

    public void setIgnoreUntrustedSSLError(boolean _ignoreUntrustedSSLError) {
        this.ignoreUntrustedSSLError = _ignoreUntrustedSSLError;
    }

    public String getPreShowScript() {
        return preShowScript;
    }

    public void setPreShowScript(String preLoadScript) {
        this.preShowScript = preLoadScript;
    }

    public boolean getPreventDeeplink() {
        return preventDeeplink;
    }

    public void setPreventDeeplink(boolean preventDeeplink) {
        this.preventDeeplink = preventDeeplink;
    }

    public boolean getOpenBlankTargetInWebView() {
        return openBlankTargetInWebView;
    }

    public void setOpenBlankTargetInWebView(boolean openBlankTargetInWebView) {
        this.openBlankTargetInWebView = openBlankTargetInWebView;
    }

    public List<String> getAuthorizedAppLinks() {
        return authorizedAppLinks;
    }

    public void setAuthorizedAppLinks(List<String> authorizedAppLinks) {
        this.authorizedAppLinks = authorizedAppLinks;
    }

    public boolean getEnableGooglePaySupport() {
        return enableGooglePaySupport;
    }

    public void setEnableGooglePaySupport(boolean enableGooglePaySupport) {
        this.enableGooglePaySupport = enableGooglePaySupport;
    }

    public boolean getEnableZoom() {
        return enableZoom;
    }

    public void setEnableZoom(boolean enableZoom) {
        this.enableZoom = enableZoom;
    }

    public List<String> getBlockedHosts() {
        if (blockedHosts != null) {
            return blockedHosts;
        }
        return new ArrayList<>();
    }

    public void setBlockedHosts(List<String> blockedHosts) {
        this.blockedHosts = blockedHosts;
    }

    public boolean isHidden() {
        return hidden;
    }

    public void setHidden(boolean hidden) {
        this.hidden = hidden;
    }

    public boolean getAllowWebViewJsVisibilityControl() {
        return allowWebViewJsVisibilityControl;
    }

    public void setAllowWebViewJsVisibilityControl(boolean allowWebViewJsVisibilityControl) {
        this.allowWebViewJsVisibilityControl = allowWebViewJsVisibilityControl;
    }

    public InvisibilityMode getInvisibilityMode() {
        return invisibilityMode;
    }

    public void setInvisibilityMode(InvisibilityMode invisibilityMode) {
        this.invisibilityMode = invisibilityMode;
    }

    public String getHttpMethod() {
        return httpMethod;
    }

    public void setHttpMethod(String httpMethod) {
        this.httpMethod = httpMethod;
    }

    public String getHttpBody() {
        return httpBody;
    }

    public void setHttpBody(String httpBody) {
        this.httpBody = httpBody;
    }

    public boolean isPopupWindowMode() {
        return popupWindowMode;
    }

    public void setPopupWindowMode(boolean popupWindowMode) {
        this.popupWindowMode = popupWindowMode;
    }

    public boolean isHiddenPopupWindow() {
        return hiddenPopupWindow;
    }

    public void setHiddenPopupWindow(boolean hiddenPopupWindow) {
        this.hiddenPopupWindow = hiddenPopupWindow;
    }

    public Options copyForPopup() {
        Options copy = new Options();
        copy.setTitle(title);
        copy.setCloseModal(false);
        copy.setCloseModalTitle(CloseModalTitle);
        copy.setCloseModalDescription(CloseModalDescription);
        copy.setCloseModalCancel(CloseModalCancel);
        copy.setCloseModalOk(CloseModalOk);
        copy.setCloseModalURLPattern(closeModalURLPattern);
        copy.setButtonNearDone(buttonNearDone);
        copy.setUrl("about:blank");
        copy.setHeaders(headers);
        copy.setCredentials(credentials);
        copy.setToolbarType(toolbarType);
        copy.setShareDisclaimer(shareDisclaimer);
        copy.setShareSubject(shareSubject);
        copy.setDisableGoBackOnNativeApplication(disableGoBackOnNativeApplication);
        copy.setActiveNativeNavigationForWebview(activeNativeNavigationForWebview);
        copy.setPresentAfterPageLoad(false);
        copy.setVisibleTitle(VisibleTitle);
        copy.setToolbarColor(ToolbarColor);
        copy.setBackgroundColor(BackgroundColor);
        copy.setArrow(ShowArrow);
        copy.setIgnoreUntrustedSSLError(ignoreUntrustedSSLError);
        copy.setPreShowScript(preShowScript);
        copy.setToolbarTextColor(toolbarTextColor);
        copy.setProxyRequestsPattern(proxyRequestsPattern);
        copy.setProxyRequests(proxyRequests);
        copy.setOutboundProxyRules(new ArrayList<>(outboundProxyRules));
        copy.setInboundProxyRules(new ArrayList<>(inboundProxyRules));
        copy.setMaterialPicker(materialPicker);
        copy.setTextZoom(textZoom);
        copy.setPreventDeeplink(preventDeeplink);
        copy.setOpenBlankTargetInWebView(openBlankTargetInWebView);
        copy.setAuthorizedAppLinks(new ArrayList<>(authorizedAppLinks));
        copy.setEnabledSafeMargin(enabledSafeBottomMargin);
        copy.setEnabledSafeTopMargin(enabledSafeTopMargin);
        copy.setUseTopInset(useTopInset);
        copy.setEnableGooglePaySupport(enableGooglePaySupport);
        copy.setBlockedHosts(new ArrayList<>(getBlockedHosts()));
        copy.setWidth(width);
        copy.setHeight(height);
        copy.setX(x);
        copy.setY(y);
        copy.setHidden(hidden || hiddenPopupWindow);
        copy.setShowScreenshotButton(showScreenshotButton);
        copy.setAllowWebViewJsVisibilityControl(allowWebViewJsVisibilityControl);
        copy.setAllowScreenshotsFromWebPage(allowScreenshotsFromWebPage);
        copy.setCaptureConsoleLogs(captureConsoleLogs);
        copy.setHandleDownloads(handleDownloads);
        copy.setInvisibilityMode(invisibilityMode);
        copy.setPopupWindowMode(true);
        copy.setHiddenPopupWindow(hiddenPopupWindow);
        return copy;
    }
}
