package com.aile.capacitor.aiff.plugin;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.PluginCall;

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

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;

public class WebViewDialog extends Dialog {

    private static final String TAG = "AiffWebView";
    
    private WebView webView;
    private LinearLayout toolbarLayout;
    private TextView titleText;
    private ImageButton backButton;
    private ImageButton forwardButton;
    private ImageButton reloadButton;
    private ImageButton closeButton;
    private ProgressBar progressBar;
    
    private final Options options;
    private final Context context;
    private PermissionHandler permissionHandler;
    private ValueCallback<Uri[]> filePathCallback;
    private PermissionRequest currentPermissionRequest;
    
    public interface PermissionHandler {
        void handleCameraPermissionRequest(PermissionRequest request);
        void handleMicrophonePermissionRequest(PermissionRequest request);
    }

    public static class Options {
        private String url;
        private String title;
        private String toolbarType = "";
        private boolean showReloadButton = false;
        private boolean closeModal = false;
        private String closeModalTitle = "关闭";
        private String closeModalDescription = "您确定要关闭此窗口吗？";
        private String closeModalOk = "关闭";
        private String closeModalCancel = "取消";
        private String toolbarColor = "#ffffff";
        private boolean visibleTitle = true;
        private boolean showArrow = false;
        private boolean isAnimated = true;
        private boolean isPresentAfterPageLoad = false;
        private boolean ignoreUntrustedSSLError = false;
        private String preShowScript;
        private Map<String, String> headers;
        private Credentials credentials;
        private boolean activeNativeNavigationForWebview = false;
        private boolean disableGoBackOnNativeApplication = false;
        private PluginCall pluginCall;
        private Callbacks callbacks;

        public static class Callbacks {
            public void urlChangeEvent(String url) {}
            public void closeEvent(String url) {}
            public void pageLoaded() {}
            public void pageLoadError() {}
            public void javascriptCallback(String message) {}
        }

        public static class Credentials {
            private String username;
            private String password;

            public Credentials(String username, String password) {
                this.username = username;
                this.password = password;
            }

            public String getUsername() { return username; }
            public String getPassword() { return password; }
        }

        // Getters and setters
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        
        public String getToolbarType() { return toolbarType; }
        public void setToolbarType(String toolbarType) { this.toolbarType = toolbarType; }
        
        public boolean isShowReloadButton() { return showReloadButton; }
        public void setShowReloadButton(boolean showReloadButton) { this.showReloadButton = showReloadButton; }
        
        public boolean isCloseModal() { 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 String getCloseModalOk() { return closeModalOk; }
        public void setCloseModalOk(String closeModalOk) { this.closeModalOk = closeModalOk; }
        
        public String getCloseModalCancel() { return closeModalCancel; }
        public void setCloseModalCancel(String closeModalCancel) { this.closeModalCancel = closeModalCancel; }
        
        public String getToolbarColor() { return toolbarColor; }
        public void setToolbarColor(String toolbarColor) { this.toolbarColor = toolbarColor; }
        
        public boolean isVisibleTitle() { return visibleTitle; }
        public void setVisibleTitle(boolean visibleTitle) { this.visibleTitle = visibleTitle; }
        
        public boolean isShowArrow() { return showArrow; }
        public void setShowArrow(boolean showArrow) { this.showArrow = showArrow; }
        
        public boolean isAnimated() { return isAnimated; }
        public void setAnimated(boolean animated) { isAnimated = animated; }
        
        public boolean isPresentAfterPageLoad() { return isPresentAfterPageLoad; }
        public void setPresentAfterPageLoad(boolean presentAfterPageLoad) { isPresentAfterPageLoad = presentAfterPageLoad; }
        
        public boolean isIgnoreUntrustedSSLError() { return ignoreUntrustedSSLError; }
        public void setIgnoreUntrustedSSLError(boolean ignoreUntrustedSSLError) { this.ignoreUntrustedSSLError = ignoreUntrustedSSLError; }
        
        public String getPreShowScript() { return preShowScript; }
        public void setPreShowScript(String preShowScript) { this.preShowScript = preShowScript; }
        
        public Map<String, String> getHeaders() { return headers; }
        public void setHeaders(Map<String, String> headers) { this.headers = headers; }
        
        public Credentials getCredentials() { return credentials; }
        public void setCredentials(Credentials credentials) { this.credentials = credentials; }
        
        public boolean isActiveNativeNavigationForWebview() { return activeNativeNavigationForWebview; }
        public void setActiveNativeNavigationForWebview(boolean activeNativeNavigationForWebview) { this.activeNativeNavigationForWebview = activeNativeNavigationForWebview; }
        
        public boolean isDisableGoBackOnNativeApplication() { return disableGoBackOnNativeApplication; }
        public void setDisableGoBackOnNativeApplication(boolean disableGoBackOnNativeApplication) { this.disableGoBackOnNativeApplication = disableGoBackOnNativeApplication; }
        
        public PluginCall getPluginCall() { return pluginCall; }
        public void setPluginCall(PluginCall pluginCall) { this.pluginCall = pluginCall; }
        
        public Callbacks getCallbacks() { return callbacks; }
        public void setCallbacks(Callbacks callbacks) { this.callbacks = callbacks; }
    }

    public WebViewDialog(@NonNull Context context, @NonNull Options options, @Nullable PermissionHandler permissionHandler) {
        super(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
        this.context = context;
        this.options = options;
        this.permissionHandler = permissionHandler;
        this.callbacks = options.getCallbacks();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setCancelable(true);
        
        // 设置窗口属性
        Window window = getWindow();
        if (window != null) {
            window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            );
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            window.setWindowAnimations(android.R.style.Animation_Dialog);
        }

        setupDialogSize();
        setupViews();
        setupWebView();
        setupToolbar();
        loadUrl();
    }

    private void setupDialogSize() {
        Window window = getWindow();
        if (window != null) {
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = WindowManager.LayoutParams.MATCH_PARENT;
            params.height = WindowManager.LayoutParams.MATCH_PARENT;
            params.gravity = Gravity.CENTER;
            window.setAttributes(params);
        }
    }

    private void setupViews() {
        FrameLayout rootLayout = new FrameLayout(context);
        rootLayout.setLayoutParams(new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT
        ));

        // 创建主布局
        LinearLayout mainLayout = new LinearLayout(context);
        mainLayout.setOrientation(LinearLayout.VERTICAL);
        mainLayout.setLayoutParams(new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT
        ));

        // 创建工具栏
        setupToolbarView(mainLayout);

        // 创建WebView容器
        FrameLayout webViewContainer = new FrameLayout(context);
        webViewContainer.setLayoutParams(new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            0,
            1.0f
        ));

        // 创建WebView
        webView = new WebView(context);
        webView.setLayoutParams(new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT
        ));

        // 创建进度条
        progressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
        progressBar.setLayoutParams(new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            4
        ));
        progressBar.setMax(100);
        progressBar.setVisibility(View.GONE);

        webViewContainer.addView(webView);
        webViewContainer.addView(progressBar);

        mainLayout.addView(webViewContainer);
        rootLayout.addView(mainLayout);
        setContentView(rootLayout);
    }

    private void setupToolbarView(LinearLayout parent) {
        if ("blank".equals(options.getToolbarType())) {
            return;
        }

        toolbarLayout = new LinearLayout(context);
        toolbarLayout.setOrientation(LinearLayout.HORIZONTAL);
        toolbarLayout.setLayoutParams(new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            dpToPx(56)
        ));
        toolbarLayout.setBackgroundColor(Color.parseColor(options.getToolbarColor()));
        toolbarLayout.setGravity(Gravity.CENTER_VERTICAL);
        toolbarLayout.setPadding(dpToPx(16), 0, dpToPx(16), 0);

        // 关闭按钮
        closeButton = new ImageButton(context);
        closeButton.setImageResource(android.R.drawable.ic_menu_close_clear_cancel);
        closeButton.setBackgroundColor(Color.TRANSPARENT);
        closeButton.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(24), dpToPx(24)));
        closeButton.setOnClickListener(v -> handleClose());

        // 标题
        titleText = new TextView(context);
        titleText.setText(options.getTitle());
        titleText.setTextColor(Color.BLACK);
        titleText.setTextSize(18);
        titleText.setLayoutParams(new LinearLayout.LayoutParams(
            0,
            LinearLayout.LayoutParams.WRAP_CONTENT,
            1.0f
        ));
        titleText.setGravity(Gravity.CENTER);
        titleText.setEllipsize(android.text.TextUtils.TruncateAt.END);
        titleText.setMaxLines(1);

        // 后退按钮
        backButton = new ImageButton(context);
        backButton.setImageResource(android.R.drawable.ic_media_previous);
        backButton.setBackgroundColor(Color.TRANSPARENT);
        backButton.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(24), dpToPx(24)));
        backButton.setOnClickListener(v -> {
            if (webView.canGoBack()) {
                webView.goBack();
            }
        });

        // 前进按钮
        forwardButton = new ImageButton(context);
        forwardButton.setImageResource(android.R.drawable.ic_media_next);
        forwardButton.setBackgroundColor(Color.TRANSPARENT);
        forwardButton.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(24), dpToPx(24)));
        forwardButton.setOnClickListener(v -> {
            if (webView.canGoForward()) {
                webView.goForward();
            }
        });

        // 重新加载按钮
        reloadButton = new ImageButton(context);
        reloadButton.setImageResource(android.R.drawable.ic_menu_rotate);
        reloadButton.setBackgroundColor(Color.TRANSPARENT);
        reloadButton.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(24), dpToPx(24)));
        reloadButton.setOnClickListener(v -> webView.reload());

        if ("navigation".equals(options.getToolbarType())) {
            toolbarLayout.addView(backButton);
            toolbarLayout.addView(forwardButton);
            toolbarLayout.addView(titleText);
            if (options.isShowReloadButton()) {
                toolbarLayout.addView(reloadButton);
            }
            toolbarLayout.addView(closeButton);
        } else if ("activity".equals(options.getToolbarType())) {
            toolbarLayout.addView(closeButton);
            toolbarLayout.addView(titleText);
            if (options.isShowReloadButton()) {
                toolbarLayout.addView(reloadButton);
            }
        } else {
            // default
            toolbarLayout.addView(closeButton);
            toolbarLayout.addView(titleText);
            if (options.isShowReloadButton()) {
                toolbarLayout.addView(reloadButton);
            }
        }

        parent.addView(toolbarLayout);
    }

    private void setupWebView() {
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setDatabaseEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setAllowFileAccess(true);
        settings.setLoadWithOverviewMode(true);
        settings.setUseWideViewPort(true);
        settings.setMediaPlaybackRequiresUserGesture(false);
        settings.setAllowFileAccessFromFileURLs(true);
        settings.setAllowUniversalAccessFromFileURLs(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            settings.setMediaPlaybackRequiresUserGesture(false);
        }

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                String url = request.getUrl().toString();
                if (!url.startsWith("http://") && !url.startsWith("https://")) {
                    try {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        context.startActivity(intent);
                        return true;
                    } catch (Exception e) {
                        Log.w(TAG, "Error opening URL: " + url, e);
                        return true;
                    }
                }
                return false;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (callbacks != null) {
                    callbacks.pageLoaded();
                }
                injectJavaScriptInterface();
                updateTitle();

                if (options.isPresentAfterPageLoad()) {
                    if (options.getPluginCall() != null) {
                        options.getPluginCall().resolve();
                    }
                }
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                super.onReceivedError(view, errorCode, description, failingUrl);
                if (callbacks != null) {
                    callbacks.pageLoadError();
                }
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                if (options.isIgnoreUntrustedSSLError()) {
                    handler.proceed();
                } else {
                    handler.cancel();
                }
            }
        });

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                progressBar.setProgress(newProgress);
                progressBar.setVisibility(newProgress < 100 ? View.VISIBLE : View.GONE);
            }

            @Override
            public void onPermissionRequest(final PermissionRequest request) {
                if (permissionHandler != null) {
                    currentPermissionRequest = request;
                    String[] resources = request.getResources();
                    for (String resource : resources) {
                        if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(resource)) {
                            permissionHandler.handleCameraPermissionRequest(request);
                            return;
                        } else if (PermissionRequest.RESOURCE_AUDIO_CAPTURE.equals(resource)) {
                            permissionHandler.handleMicrophonePermissionRequest(request);
                            return;
                        }
                    }
                }
                request.grant(request.getResources());
            }

            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                WebViewDialog.this.filePathCallback = filePathCallback;
                return true;
            }
        });

        webView.addJavascriptInterface(new JavaScriptInterface(), "AndroidInterface");
    }

    private void injectJavaScriptInterface() {
        String script = "if (!window.mobileApp) { " +
                "    window.mobileApp = { " +
                "        postMessage: function(message) { " +
                "            if (window.AndroidInterface) { " +
                "                window.AndroidInterface.postMessage(JSON.stringify(message)); " +
                "            } " +
                "        } " +
                "    }; " +
                "}" +
                "if (!window.postMessageToJS) { " +
                "    window.postMessageToJS = function(detail) { " +
                "        window.dispatchEvent(new CustomEvent('messageFromNative', { detail: detail })); " +
                "    }; " +
                "}";
        webView.evaluateJavascript(script, null);
    }

    private void loadUrl() {
        if (options.getUrl() != null) {
            // 添加headers
            Map<String, String> headers = new HashMap<>();
            if (options.getHeaders() != null) {
                headers.putAll(options.getHeaders());
            }
            webView.loadUrl(options.getUrl(), headers);
        }
    }

    private void updateTitle() {
        if (options.isVisibleTitle() && titleText != null) {
            titleText.setText(webView.getTitle());
        }
    }

    private void handleClose() {
        if (options.isCloseModal()) {
            new AlertDialog.Builder(context)
                    .setTitle(options.getCloseModalTitle())
                    .setMessage(options.getCloseModalDescription())
                    .setPositiveButton(options.getCloseModalOk(), (dialog, which) -> {
                        closeWebView();
                    })
                    .setNegativeButton(options.getCloseModalCancel(), null)
                    .show();
        } else {
            closeWebView();
        }
    }

    private void closeWebView() {
        if (callbacks != null) {
            callbacks.closeEvent(webView.getUrl());
        }
        dismiss();
    }

    public void postMessageToJS(Object detail) {
        if (webView != null) {
            try {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("detail", detail);
                String jsonDetail = jsonObject.toString();
                String script = "window.dispatchEvent(new CustomEvent('messageFromNative', " + jsonDetail + "));";
                webView.evaluateJavascript(script, null);
            } catch (JSONException e) {
                Log.e(TAG, "Error sending message to JS: " + e.getMessage());
            }
        }
    }

    public void executeScript(String code) {
        if (webView != null) {
            webView.evaluateJavascript(code, null);
        }
    }

    public void setUrl(String url) {
        if (webView != null) {
            webView.loadUrl(url);
        }
    }

    public void reload() {
        if (webView != null) {
            webView.reload();
        }
    }

    public class JavaScriptInterface {
        @android.webkit.JavascriptInterface
        public void postMessage(String message) {
            if (callbacks != null) {
                callbacks.javascriptCallback(message);
            }
        }
    }

    private int dpToPx(int dp) {
        return (int) (dp * context.getResources().getDisplayMetrics().density);
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack() && 
            ("navigation".equals(options.getToolbarType()) || options.isActiveNativeNavigationForWebview())) {
            webView.goBack();
        } else if (!options.isDisableGoBackOnNativeApplication()) {
            super.onBackPressed();
        }
    }

    @Override
    public void dismiss() {
        if (webView != null) {
            webView.stopLoading();
            webView.destroy();
        }
        super.dismiss();
    }
}