package chat.vojo.app;

import android.content.Context;
import android.webkit.HttpAuthHandler;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.getcapacitor.Bridge;
import com.getcapacitor.BridgeWebViewClient;

/**
 * Extends Capacitor's {@link BridgeWebViewClient} (preserving the local-server
 * shouldInterceptRequest / launchIntent / error-page wiring via super) and adds
 * exactly two proxy hooks (proxy_android_impl.md §1, §3 F5):
 *
 *  1. onReceivedHttpAuthRequest — answer the proxy/relay 407 with the stored
 *     creds / relay token. This is the (officially unsupported) Chromium
 *     mechanism for proxy auth, and is the Phase-0 linchpin: it must be
 *     validated on a real device. We only ever answer when the 407 comes from
 *     OUR active proxy/relay endpoint; everything else defers to super (cancel).
 *
 *  2. onReceivedError — surface a genuinely dead/wrong proxy as a status, but
 *     ONLY for connection-level error codes (CONNECT / PROXY_AUTHENTICATION /
 *     HOST_LOOKUP). Per-resource media failures (avatars cancelled on scroll,
 *     slow-image timeouts) must NOT flag the proxy as down — that flapped the
 *     status to "unavailable" while the proxy was healthy. HTTP error responses
 *     (incl. 5xx) are deliberately NOT treated as proxy failures: a status reply
 *     proves the request reached the server through the proxy. The JS /versions
 *     probe is the authoritative reachability oracle.
 *
 * We deliberately do NOT override onReceivedSslError — TLS validation stays at
 * the system default (no weakening, proxy_support.md §15).
 */
public class ProxyBridgeWebViewClient extends BridgeWebViewClient {

    private final Context appContext;

    public ProxyBridgeWebViewClient(Bridge bridge) {
        super(bridge);
        this.appContext = bridge.getActivity().getApplicationContext();
    }

    @Override
    public void onReceivedHttpAuthRequest(
        WebView view, HttpAuthHandler handler, String host, String realm) {
        String[] auth = ProxyManager.get(appContext).getProxyAuth(host, realm);
        if (auth != null) {
            handler.proceed(auth[0], auth[1]);
            return;
        }
        super.onReceivedHttpAuthRequest(view, handler, host, realm);
    }

    @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        super.onReceivedError(view, request, error);
        // Only flag the proxy as down for unambiguous connection-level failures.
        // The WebView fires onReceivedError for every failed subresource, and the
        // only homeserver-origin loads it makes are MEDIA (avatars/images), which
        // fail routinely and benignly (cancelled on scroll, transient resets,
        // slow-image timeouts) even when the proxy is perfectly healthy. Flagging
        // any of those flapped the status to "unavailable" until a manual
        // recheck. A hung/slow single resource (TIMEOUT/IO) is left to the
        // authoritative JS /versions probe rather than latched here.
        if (error == null) return;
        int code = error.getErrorCode();
        if (code == WebViewClient.ERROR_CONNECT
            || code == WebViewClient.ERROR_PROXY_AUTHENTICATION
            || code == WebViewClient.ERROR_HOST_LOOKUP) {
            notifyProxyError(request);
        }
    }

    private void notifyProxyError(WebResourceRequest request) {
        if (request == null || request.getUrl() == null) return;
        String host = request.getUrl().getHost();
        // ProxyManager filters to the active (homeserver) host; external origins
        // failing is not a proxy problem.
        ProxyManager.get(appContext).onWebViewError(host);
    }
}
