// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/widgets.dart';
// ignore: implementation_imports
import 'package:webview_flutter_platform_interface/src/webview_flutter_platform_interface_legacy.dart';

import '../android_webview.dart' as android_webview;
import '../weak_reference_utils.dart';
import 'webview_android_cookie_manager.dart';

/// Creates a [Widget] with a [android_webview.WebView].
class WebViewAndroidWidget extends StatefulWidget {
  /// Constructs a [WebViewAndroidWidget].
  const WebViewAndroidWidget({
    super.key,
    required this.creationParams,
    required this.useHybridComposition,
    required this.callbacksHandler,
    required this.javascriptChannelRegistry,
    required this.onBuildWidget,
    @visibleForTesting this.webViewProxy = const WebViewProxy(),
    @visibleForTesting
        this.flutterAssetManager = const android_webview.FlutterAssetManager(),
    @visibleForTesting this.webStorage,
  });

  /// Initial parameters used to setup the WebView.
  final CreationParams creationParams;

  /// Whether the [android_webview.WebView] will be rendered with an [AndroidViewSurface].
  ///
  /// This implementation uses hybrid composition to render the
  /// [WebViewAndroidWidget]. This comes at the cost of some performance on
  /// Android versions below 10. See
  /// https://flutter.dev/docs/development/platform-integration/platform-views#performance
  /// for more information.
  ///
  /// Defaults to false.
  final bool useHybridComposition;

  /// Handles callbacks that are made by [android_webview.WebViewClient], [android_webview.DownloadListener], and [android_webview.WebChromeClient].
  final WebViewPlatformCallbacksHandler callbacksHandler;

  /// Manages named JavaScript channels and forwarding incoming messages on the correct channel.
  final JavascriptChannelRegistry javascriptChannelRegistry;

  /// Handles constructing [android_webview.WebView]s and calling static methods.
  ///
  /// This should only be changed for testing purposes.
  final WebViewProxy webViewProxy;

  /// Manages access to Flutter assets that are part of the Android App bundle.
  ///
  /// This should only be changed for testing purposes.
  final android_webview.FlutterAssetManager flutterAssetManager;

  /// Callback to build a widget once [android_webview.WebView] has been initialized.
  final Widget Function(WebViewAndroidPlatformController controller)
      onBuildWidget;

  /// Manages the JavaScript storage APIs.
  final android_webview.WebStorage? webStorage;

  @override
  State<StatefulWidget> createState() => _WebViewAndroidWidgetState();
}

class _WebViewAndroidWidgetState extends State<WebViewAndroidWidget> {
  late final WebViewAndroidPlatformController controller;

  @override
  void initState() {
    super.initState();
    controller = WebViewAndroidPlatformController(
      useHybridComposition: widget.useHybridComposition,
      creationParams: widget.creationParams,
      callbacksHandler: widget.callbacksHandler,
      javascriptChannelRegistry: widget.javascriptChannelRegistry,
      webViewProxy: widget.webViewProxy,
      flutterAssetManager: widget.flutterAssetManager,
      webStorage: widget.webStorage,
    );
  }

  @override
  Widget build(BuildContext context) {
    return widget.onBuildWidget(controller);
  }
}

/// Implementation of [WebViewPlatformController] with the Android WebView api.
class WebViewAndroidPlatformController extends WebViewPlatformController {
  /// Construct a [WebViewAndroidPlatformController].
  WebViewAndroidPlatformController({
    required bool useHybridComposition,
    required CreationParams creationParams,
    required this.callbacksHandler,
    required this.javascriptChannelRegistry,
    @visibleForTesting this.webViewProxy = const WebViewProxy(),
    @visibleForTesting
        this.flutterAssetManager = const android_webview.FlutterAssetManager(),
    @visibleForTesting android_webview.WebStorage? webStorage,
  })  : webStorage = webStorage ?? android_webview.WebStorage.instance,
        assert(creationParams.webSettings?.hasNavigationDelegate != null),
        super(callbacksHandler) {
    webView = webViewProxy.createWebView(
      useHybridComposition: useHybridComposition,
    );

    webView.settings.setDomStorageEnabled(true);
    webView.settings.setJavaScriptCanOpenWindowsAutomatically(true);
    webView.settings.setSupportMultipleWindows(true);
    webView.settings.setLoadWithOverviewMode(true);
    webView.settings.setUseWideViewPort(true);
    webView.settings.setDisplayZoomControls(false);
    webView.settings.setBuiltInZoomControls(true);

    _setCreationParams(creationParams);
    webView.setDownloadListener(downloadListener);
    webView.setWebChromeClient(webChromeClient);
    webView.setWebViewClient(webViewClient);

    final String? initialUrl = creationParams.initialUrl;
    if (initialUrl != null) {
      loadUrl(initialUrl, <String, String>{});
    }
  }

  final Map<String, WebViewAndroidJavaScriptChannel> _javaScriptChannels =
      <String, WebViewAndroidJavaScriptChannel>{};

  late final android_webview.WebViewClient _webViewClient = withWeakRefenceTo(
      this, (WeakReference<WebViewAndroidPlatformController> weakReference) {
    return webViewProxy.createWebViewClient(
      onPageStarted: (_, String url) {
        weakReference.target?.callbacksHandler.onPageStarted(url);
      },
      onPageFinished: (_, String url) {
        weakReference.target?.callbacksHandler.onPageFinished(url);
      },
      onReceivedError: (
        _,
        int errorCode,
        String description,
        String failingUrl,
      ) {
        weakReference.target?.callbacksHandler
            .onWebResourceError(WebResourceError(
          errorCode: errorCode,
          description: description,
          failingUrl: failingUrl,
          errorType: _errorCodeToErrorType(errorCode),
        ));
      },
      onReceivedRequestError: (
        _,
        android_webview.WebResourceRequest request,
        android_webview.WebResourceError error,
      ) {
        if (request.isForMainFrame) {
          weakReference.target?.callbacksHandler
              .onWebResourceError(WebResourceError(
            errorCode: error.errorCode,
            description: error.description,
            failingUrl: request.url,
            errorType: _errorCodeToErrorType(error.errorCode),
          ));
        }
      },
      urlLoading: (_, String url) {
        weakReference.target?._handleNavigationRequest(
          url: url,
          isForMainFrame: true,
        );
      },
      requestLoading: (_, android_webview.WebResourceRequest request) {
        weakReference.target?._handleNavigationRequest(
          url: request.url,
          isForMainFrame: request.isForMainFrame,
        );
      },
    );
  });

  bool _hasNavigationDelegate = false;
  bool _hasProgressTracking = false;

  /// Represents the WebView maintained by platform code.
  late final android_webview.WebView webView;

  /// Handles callbacks that are made by [android_webview.WebViewClient], [android_webview.DownloadListener], and [android_webview.WebChromeClient].
  final WebViewPlatformCallbacksHandler callbacksHandler;

  /// Manages named JavaScript channels and forwarding incoming messages on the correct channel.
  final JavascriptChannelRegistry javascriptChannelRegistry;

  /// Handles constructing [android_webview.WebView]s and calling static methods.
  ///
  /// This should only be changed for testing purposes.
  final WebViewProxy webViewProxy;

  /// Manages access to Flutter assets that are part of the Android App bundle.
  ///
  /// This should only be changed for testing purposes.
  final android_webview.FlutterAssetManager flutterAssetManager;

  /// Receives callbacks when content should be downloaded instead.
  @visibleForTesting
  late final android_webview.DownloadListener downloadListener =
      android_webview.DownloadListener(
    onDownloadStart: withWeakRefenceTo(
      this,
      (WeakReference<WebViewAndroidPlatformController> weakReference) {
        return (
          String url,
          String userAgent,
          String contentDisposition,
          String mimetype,
          int contentLength,
        ) {
          weakReference.target?._handleNavigationRequest(
            url: url,
            isForMainFrame: true,
          );
        };
      },
    ),
  );

  /// Handles JavaScript dialogs, favicons, titles, new windows, and the progress for [android_webview.WebView].
  @visibleForTesting
  late final android_webview.WebChromeClient webChromeClient =
      android_webview.WebChromeClient(
          onProgressChanged: withWeakRefenceTo(
    this,
    (WeakReference<WebViewAndroidPlatformController> weakReference) {
      return (_, int progress) {
        final WebViewAndroidPlatformController? controller =
            weakReference.target;
        if (controller != null && controller._hasProgressTracking) {
          controller.callbacksHandler.onProgress(progress);
        }
      };
    },
  ));

  /// Manages the JavaScript storage APIs.
  final android_webview.WebStorage webStorage;

  /// Receive various notifications and requests for [android_webview.WebView].
  @visibleForTesting
  android_webview.WebViewClient get webViewClient => _webViewClient;

  @override
  Future<void> loadHtmlString(String html, {String? baseUrl}) {
    return webView.loadDataWithBaseUrl(
      baseUrl: baseUrl,
      data: html,
      mimeType: 'text/html',
    );
  }

  @override
  Future<void> loadFile(String absoluteFilePath) {
    final String url = absoluteFilePath.startsWith('file://')
        ? absoluteFilePath
        : 'file://$absoluteFilePath';

    webView.settings.setAllowFileAccess(true);
    return webView.loadUrl(url, <String, String>{});
  }

  @override
  Future<void> loadFlutterAsset(String key) async {
    final String assetFilePath =
        await flutterAssetManager.getAssetFilePathByName(key);
    final List<String> pathElements = assetFilePath.split('/');
    final String fileName = pathElements.removeLast();
    final List<String?> paths =
        await flutterAssetManager.list(pathElements.join('/'));

    if (!paths.contains(fileName)) {
      throw ArgumentError(
        'Asset for key "$key" not found.',
        'key',
      );
    }

    return webView.loadUrl(
      'file:///android_asset/$assetFilePath',
      <String, String>{},
    );
  }

  @override
  Future<void> loadUrl(
    String url,
    Map<String, String>? headers,
  ) {
    return webView.loadUrl(url, headers ?? <String, String>{});
  }

  /// When making a POST request, headers are ignored. As a workaround, make
  /// the request manually and load the response data using [loadHTMLString].
  @override
  Future<void> loadRequest(
    WebViewRequest request,
  ) async {
    if (!request.uri.hasScheme) {
      throw ArgumentError('WebViewRequest#uri is required to have a scheme.');
    }
    switch (request.method) {
      case WebViewRequestMethod.get:
        return webView.loadUrl(request.uri.toString(), request.headers);
      case WebViewRequestMethod.post:
        return webView.postUrl(
            request.uri.toString(), request.body ?? Uint8List(0));
      default:
        throw UnimplementedError(
          'This version of webview_android_widget currently has no implementation for HTTP method ${request.method.serialize()} in loadRequest.',
        );
    }
  }

  @override
  Future<String?> currentUrl() => webView.getUrl();

  @override
  Future<bool> canGoBack() => webView.canGoBack();

  @override
  Future<bool> canGoForward() => webView.canGoForward();

  @override
  Future<void> goBack() => webView.goBack();

  @override
  Future<void> goForward() => webView.goForward();

  @override
  Future<void> reload() => webView.reload();

  @override
  Future<void> clearCache() {
    webView.clearCache(true);
    return webStorage.deleteAllData();
  }

  @override
  Future<void> updateSettings(WebSettings setting) async {
    _hasProgressTracking = setting.hasProgressTracking ?? _hasProgressTracking;
    await Future.wait(<Future<void>>[
      _setUserAgent(setting.userAgent),
      if (setting.hasNavigationDelegate != null)
        _setHasNavigationDelegate(setting.hasNavigationDelegate!),
      if (setting.javascriptMode != null)
        _setJavaScriptMode(setting.javascriptMode!),
      if (setting.debuggingEnabled != null)
        _setDebuggingEnabled(setting.debuggingEnabled!),
      if (setting.zoomEnabled != null) _setZoomEnabled(setting.zoomEnabled!),
    ]);
  }

  @override
  Future<String> evaluateJavascript(String javascript) async {
    return runJavascriptReturningResult(javascript);
  }

  @override
  Future<void> runJavascript(String javascript) async {
    await webView.evaluateJavascript(javascript);
  }

  @override
  Future<String> runJavascriptReturningResult(String javascript) async {
    return await webView.evaluateJavascript(javascript) ?? '';
  }

  @override
  Future<void> addJavascriptChannels(Set<String> javascriptChannelNames) {
    return Future.wait(
      javascriptChannelNames.where(
        (String channelName) {
          return !_javaScriptChannels.containsKey(channelName);
        },
      ).map<Future<void>>(
        (String channelName) {
          final WebViewAndroidJavaScriptChannel javaScriptChannel =
              WebViewAndroidJavaScriptChannel(
                  channelName, javascriptChannelRegistry);
          _javaScriptChannels[channelName] = javaScriptChannel;
          return webView.addJavaScriptChannel(javaScriptChannel);
        },
      ),
    );
  }

  @override
  Future<void> removeJavascriptChannels(
    Set<String> javascriptChannelNames,
  ) {
    return Future.wait(
      javascriptChannelNames.where(
        (String channelName) {
          return _javaScriptChannels.containsKey(channelName);
        },
      ).map<Future<void>>(
        (String channelName) {
          final WebViewAndroidJavaScriptChannel javaScriptChannel =
              _javaScriptChannels[channelName]!;
          _javaScriptChannels.remove(channelName);
          return webView.removeJavaScriptChannel(javaScriptChannel);
        },
      ),
    );
  }

  @override
  Future<String?> getTitle() => webView.getTitle();

  @override
  Future<void> scrollTo(int x, int y) => webView.scrollTo(x, y);

  @override
  Future<void> scrollBy(int x, int y) => webView.scrollBy(x, y);

  @override
  Future<int> getScrollX() => webView.getScrollX();

  @override
  Future<int> getScrollY() => webView.getScrollY();

  void _setCreationParams(CreationParams creationParams) {
    final WebSettings? webSettings = creationParams.webSettings;
    if (webSettings != null) {
      updateSettings(webSettings);
    }

    final String? userAgent = creationParams.userAgent;
    if (userAgent != null) {
      webView.settings.setUserAgentString(userAgent);
    }

    webView.settings.setMediaPlaybackRequiresUserGesture(
      creationParams.autoMediaPlaybackPolicy !=
          AutoMediaPlaybackPolicy.always_allow,
    );

    final Color? backgroundColor = creationParams.backgroundColor;
    if (backgroundColor != null) {
      webView.setBackgroundColor(backgroundColor);
    }

    addJavascriptChannels(creationParams.javascriptChannelNames);

    // TODO(BeMacized): Remove once platform implementations
    // are able to register themselves (Flutter >=2.8),
    // https://github.com/flutter/flutter/issues/94224
    WebViewCookieManagerPlatform.instance ??= WebViewAndroidCookieManager();

    creationParams.cookies
        .forEach(WebViewCookieManagerPlatform.instance!.setCookie);
  }

  Future<void> _setHasNavigationDelegate(bool hasNavigationDelegate) {
    _hasNavigationDelegate = hasNavigationDelegate;
    return _webViewClient.setSynchronousReturnValueForShouldOverrideUrlLoading(
      hasNavigationDelegate,
    );
  }

  Future<void> _setJavaScriptMode(JavascriptMode mode) {
    switch (mode) {
      case JavascriptMode.disabled:
        return webView.settings.setJavaScriptEnabled(false);
      case JavascriptMode.unrestricted:
        return webView.settings.setJavaScriptEnabled(true);
    }
  }

  Future<void> _setDebuggingEnabled(bool debuggingEnabled) {
    return webViewProxy.setWebContentsDebuggingEnabled(debuggingEnabled);
  }

  Future<void> _setUserAgent(WebSetting<String?> userAgent) {
    if (userAgent.isPresent) {
      // If the string is empty, the system default value will be used.
      return webView.settings.setUserAgentString(userAgent.value ?? '');
    }

    return Future<void>.value();
  }

  Future<void> _setZoomEnabled(bool zoomEnabled) {
    return webView.settings.setSupportZoom(zoomEnabled);
  }

  static WebResourceErrorType _errorCodeToErrorType(int errorCode) {
    switch (errorCode) {
      case android_webview.WebViewClient.errorAuthentication:
        return WebResourceErrorType.authentication;
      case android_webview.WebViewClient.errorBadUrl:
        return WebResourceErrorType.badUrl;
      case android_webview.WebViewClient.errorConnect:
        return WebResourceErrorType.connect;
      case android_webview.WebViewClient.errorFailedSslHandshake:
        return WebResourceErrorType.failedSslHandshake;
      case android_webview.WebViewClient.errorFile:
        return WebResourceErrorType.file;
      case android_webview.WebViewClient.errorFileNotFound:
        return WebResourceErrorType.fileNotFound;
      case android_webview.WebViewClient.errorHostLookup:
        return WebResourceErrorType.hostLookup;
      case android_webview.WebViewClient.errorIO:
        return WebResourceErrorType.io;
      case android_webview.WebViewClient.errorProxyAuthentication:
        return WebResourceErrorType.proxyAuthentication;
      case android_webview.WebViewClient.errorRedirectLoop:
        return WebResourceErrorType.redirectLoop;
      case android_webview.WebViewClient.errorTimeout:
        return WebResourceErrorType.timeout;
      case android_webview.WebViewClient.errorTooManyRequests:
        return WebResourceErrorType.tooManyRequests;
      case android_webview.WebViewClient.errorUnknown:
        return WebResourceErrorType.unknown;
      case android_webview.WebViewClient.errorUnsafeResource:
        return WebResourceErrorType.unsafeResource;
      case android_webview.WebViewClient.errorUnsupportedAuthScheme:
        return WebResourceErrorType.unsupportedAuthScheme;
      case android_webview.WebViewClient.errorUnsupportedScheme:
        return WebResourceErrorType.unsupportedScheme;
    }

    throw ArgumentError(
      'Could not find a WebResourceErrorType for errorCode: $errorCode',
    );
  }

  void _handleNavigationRequest({
    required String url,
    required bool isForMainFrame,
  }) {
    if (!_hasNavigationDelegate) {
      return;
    }

    final FutureOr<bool> returnValue = callbacksHandler.onNavigationRequest(
      url: url,
      isForMainFrame: isForMainFrame,
    );

    if (returnValue is bool && returnValue) {
      loadUrl(url, <String, String>{});
    } else if (returnValue is Future<bool>) {
      returnValue.then((bool shouldLoadUrl) {
        if (shouldLoadUrl) {
          loadUrl(url, <String, String>{});
        }
      });
    }
  }
}

/// Exposes a channel to receive calls from javaScript.
class WebViewAndroidJavaScriptChannel
    extends android_webview.JavaScriptChannel {
  /// Creates a [WebViewAndroidJavaScriptChannel].
  WebViewAndroidJavaScriptChannel(
    super.channelName,
    this.javascriptChannelRegistry,
  ) : super(
          postMessage: withWeakRefenceTo(
            javascriptChannelRegistry,
            (WeakReference<JavascriptChannelRegistry> weakReference) {
              return (String message) {
                weakReference.target?.onJavascriptChannelMessage(
                  channelName,
                  message,
                );
              };
            },
          ),
        );

  /// Manages named JavaScript channels and forwarding incoming messages on the correct channel.
  final JavascriptChannelRegistry javascriptChannelRegistry;
}

/// Handles constructing [android_webview.WebView]s and calling static methods.
///
/// This should only be used for testing purposes.
@visibleForTesting
class WebViewProxy {
  /// Creates a [WebViewProxy].
  const WebViewProxy();

  /// Constructs a [android_webview.WebView].
  android_webview.WebView createWebView({required bool useHybridComposition}) {
    return android_webview.WebView(useHybridComposition: useHybridComposition);
  }

  /// Constructs a [android_webview.WebViewClient].
  android_webview.WebViewClient createWebViewClient({
    void Function(android_webview.WebView webView, String url)? onPageStarted,
    void Function(android_webview.WebView webView, String url)? onPageFinished,
    void Function(
      android_webview.WebView webView,
      android_webview.WebResourceRequest request,
      android_webview.WebResourceError error,
    )?
        onReceivedRequestError,
    void Function(
      android_webview.WebView webView,
      int errorCode,
      String description,
      String failingUrl,
    )?
        onReceivedError,
    void Function(android_webview.WebView webView,
            android_webview.WebResourceRequest request)?
        requestLoading,
    void Function(android_webview.WebView webView, String url)? urlLoading,
  }) {
    return android_webview.WebViewClient(
      onPageStarted: onPageStarted,
      onPageFinished: onPageFinished,
      onReceivedRequestError: onReceivedRequestError,
      onReceivedError: onReceivedError,
      requestLoading: requestLoading,
      urlLoading: urlLoading,
    );
  }

  /// Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application.
  ///
  /// This flag can be enabled in order to facilitate debugging of web layouts
  /// and JavaScript code running inside WebViews. Please refer to
  /// [android_webview.WebView] documentation for the debugging guide. The
  /// default is false.
  ///
  /// See [android_webview.WebView].setWebContentsDebuggingEnabled.
  Future<void> setWebContentsDebuggingEnabled(bool enabled) {
    return android_webview.WebView.setWebContentsDebuggingEnabled(enabled);
  }
}
