package com.aile.capacitor.aiff.plugin;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.webkit.PermissionRequest;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import com.getcapacitor.annotation.PermissionCallback;

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

import java.util.HashMap;
import java.util.Map;

@CapacitorPlugin(
    name = "AiffWebView",
    permissions = {
        @Permission(strings = {Manifest.permission.CAMERA}),
        @Permission(strings = {Manifest.permission.RECORD_AUDIO}),
        @Permission(strings = {Manifest.permission.READ_EXTERNAL_STORAGE}),
        @Permission(strings = {Manifest.permission.WRITE_EXTERNAL_STORAGE})
    }
)
public class AiffWebViewPlugin extends Plugin implements WebViewDialog.PermissionHandler {

    private static final int CAMERA_PERMISSION_REQUEST_CODE = 1001;
    private static final int MICROPHONE_PERMISSION_REQUEST_CODE = 1002;
    
    private WebViewDialog currentDialog;
    private PermissionRequest pendingCameraRequest;
    private PermissionRequest pendingMicrophoneRequest;

    @PluginMethod
    public void openWebView(PluginCall call) {
        String url = call.getString("url");
        if (url == null || url.isEmpty()) {
            call.reject("URL is required");
            return;
        }

        WebViewDialog.Options options = new WebViewDialog.Options();
        options.setUrl(url);
        options.setTitle(call.getString("title", "新窗口"));
        options.setToolbarType(call.getString("toolbarType", ""));
        options.setShowReloadButton(call.getBoolean("showReloadButton", false));
        options.setCloseModal(call.getBoolean("closeModal", false));
        options.setCloseModalTitle(call.getString("closeModalTitle", "关闭"));
        options.setCloseModalDescription(call.getString("closeModalDescription", "您确定要关闭此窗口吗？"));
        options.setCloseModalOk(call.getString("closeModalOk", "关闭"));
        options.setCloseModalCancel(call.getString("closeModalCancel", "取消"));
        options.setToolbarColor(call.getString("toolbarColor", "#ffffff"));
        options.setVisibleTitle(call.getBoolean("visibleTitle", true));
        options.setShowArrow(call.getBoolean("showArrow", false));
        options.setAnimated(call.getBoolean("isAnimated", true));
        options.setPresentAfterPageLoad(call.getBoolean("isPresentAfterPageLoad", false));
        options.setIgnoreUntrustedSSLError(call.getBoolean("ignoreUntrustedSSLError", false));
        options.setPreShowScript(call.getString("preShowScript"));
        options.setActiveNativeNavigationForWebview(call.getBoolean("activeNativeNavigationForWebview", false));
        options.setDisableGoBackOnNativeApplication(call.getBoolean("disableGoBackOnNativeApplication", false));
        options.setPluginCall(call);

        // 设置headers
        JSObject headersObj = call.getObject("headers");
        if (headersObj != null) {
            Map<String, String> headers = new HashMap<>();
            try {
                JSONObject jsonObject = headersObj.toJSONObject();
                for (String key : jsonObject.keySet()) {
                    headers.put(key, jsonObject.getString(key));
                }
                options.setHeaders(headers);
            } catch (JSONException e) {
                call.reject("Failed to parse headers");
                return;
            }
        }

        // 设置credentials
        JSObject credentialsObj = call.getObject("credentials");
        if (credentialsObj != null) {
            String username = credentialsObj.getString("username", "");
            String password = credentialsObj.getString("password", "");
            options.setCredentials(new WebViewDialog.Options.Credentials(username, password));
        }

        // 设置callbacks
        options.setCallbacks(new WebViewDialog.Options.Callbacks() {
            @Override
            public void urlChangeEvent(String url) {
                JSObject ret = new JSObject();
                ret.put("url", url);
                notifyListeners("urlChangeEvent", ret);
            }

            @Override
            public void closeEvent(String url) {
                JSObject ret = new JSObject();
                ret.put("url", url);
                notifyListeners("closeEvent", ret);
                if (currentDialog != null) {
                    currentDialog = null;
                }
            }

            @Override
            public void pageLoaded() {
                notifyListeners("browserPageLoaded", new JSObject());
            }

            @Override
            public void pageLoadError() {
                notifyListeners("pageLoadError", new JSObject());
            }

            @Override
            public void javascriptCallback(String message) {
                JSObject ret = new JSObject();
                try {
                    JSONObject jsonMessage = new JSONObject(message);
                    ret.put("detail", jsonMessage);
                } catch (JSONException e) {
                    ret.put("detail", message);
                }
                ret.put("rawMessage", message);
                notifyListeners("messageFromWebview", ret);
            }
        });

        Activity activity = getActivity();
        if (activity == null) {
            call.reject("Activity is null");
            return;
        }

        activity.runOnUiThread(() -> {
            currentDialog = new WebViewDialog(activity, options, this);
            if (options.isPresentAfterPageLoad()) {
                // 延迟显示，等待页面加载完成
                currentDialog.show();
            } else {
                currentDialog.show();
                call.resolve();
            }
        });
    }

    @PluginMethod
    public void executeScript(PluginCall call) {
        String code = call.getString("code");
        if (code == null || code.isEmpty()) {
            call.reject("Code is required");
            return;
        }

        if (currentDialog != null) {
            getActivity().runOnUiThread(() -> {
                currentDialog.executeScript(code);
                call.resolve();
            });
        } else {
            call.reject("No active webview");
        }
    }

    @PluginMethod
    public void postMessage(PluginCall call) {
        JSObject detail = call.getObject("detail");
        if (detail == null) {
            call.reject("Detail is required");
            return;
        }

        if (currentDialog != null) {
            getActivity().runOnUiThread(() -> {
                currentDialog.postMessageToJS(detail.toJSONObject());
                call.resolve();
            });
        } else {
            call.reject("No active webview");
        }
    }

    @PluginMethod
    public void setUrl(PluginCall call) {
        String url = call.getString("url");
        if (url == null || url.isEmpty()) {
            call.reject("URL is required");
            return;
        }

        if (currentDialog != null) {
            getActivity().runOnUiThread(() -> {
                currentDialog.setUrl(url);
                call.resolve();
            });
        } else {
            call.reject("No active webview");
        }
    }

    @PluginMethod
    public void reload(PluginCall call) {
        if (currentDialog != null) {
            getActivity().runOnUiThread(() -> {
                currentDialog.reload();
                call.resolve();
            });
        } else {
            call.reject("No active webview");
        }
    }

    @Override
    public void handleCameraPermissionRequest(PermissionRequest request) {
        pendingCameraRequest = request;
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) 
            == PackageManager.PERMISSION_GRANTED) {
            request.grant(request.getResources());
        } else {
            ActivityCompat.requestPermissions(
                getActivity(),
                new String[]{Manifest.permission.CAMERA},
                CAMERA_PERMISSION_REQUEST_CODE
            );
        }
    }

    @Override
    public void handleMicrophonePermissionRequest(PermissionRequest request) {
        pendingMicrophoneRequest = request;
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.RECORD_AUDIO) 
            == PackageManager.PERMISSION_GRANTED) {
            request.grant(request.getResources());
        } else {
            ActivityCompat.requestPermissions(
                getActivity(),
                new String[]{Manifest.permission.RECORD_AUDIO},
                MICROPHONE_PERMISSION_REQUEST_CODE
            );
        }
    }

    @PermissionCallback
    private void cameraPermissionCallback() {
        if (pendingCameraRequest != null) {
            if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) 
                == PackageManager.PERMISSION_GRANTED) {
                pendingCameraRequest.grant(pendingCameraRequest.getResources());
            } else {
                pendingCameraRequest.deny();
            }
            pendingCameraRequest = null;
        }
    }

    @PermissionCallback
    private void microphonePermissionCallback() {
        if (pendingMicrophoneRequest != null) {
            if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.RECORD_AUDIO) 
                == PackageManager.PERMISSION_GRANTED) {
                pendingMicrophoneRequest.grant(pendingMicrophoneRequest.getResources());
            } else {
                pendingMicrophoneRequest.deny();
            }
            pendingMicrophoneRequest = null;
        }
    }
}