// 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.

part of google_maps_flutter_web;

// Default values for when the gmaps objects return null/undefined values.
final gmaps.LatLng _nullGmapsLatLng = gmaps.LatLng(0, 0);
final gmaps.LatLngBounds _nullGmapsLatLngBounds =
    gmaps.LatLngBounds(_nullGmapsLatLng, _nullGmapsLatLng);

// Defaults taken from the Google Maps Platform SDK documentation.
const String _defaultCssColor = '#000000';
const double _defaultCssOpacity = 0.0;

// Converts a [Color] into a valid CSS value #RRGGBB.
String _getCssColor(Color color) {
  if (color == null) {
    return _defaultCssColor;
  }
  return '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}';
}

// Extracts the opacity from a [Color].
double _getCssOpacity(Color color) {
  if (color == null) {
    return _defaultCssOpacity;
  }
  return color.opacity;
}

// Converts options from the plugin into gmaps.MapOptions that can be used by the JS SDK.
// The following options are not handled here, for various reasons:
// The following are not available in web, because the map doesn't rotate there:
//   compassEnabled
//   rotateGesturesEnabled
//   tiltGesturesEnabled
// mapToolbarEnabled is unused in web, there's no "map toolbar"
// myLocationButtonEnabled Widget not available in web yet, it needs to be built on top of the maps widget
//   See: https://developers.google.com/maps/documentation/javascript/examples/control-custom
// myLocationEnabled needs to be built through dart:html navigator.geolocation
//   See: https://api.dart.dev/stable/2.8.4/dart-html/Geolocation-class.html
// trafficEnabled is handled when creating the GMap object, since it needs to be added as a layer.
// trackCameraPosition is just a boolan value that indicates if the map has an onCameraMove handler.
// indoorViewEnabled seems to not have an equivalent in web
// buildingsEnabled seems to not have an equivalent in web
// padding seems to behave differently in web than mobile. You can't move UI elements in web.
gmaps.MapOptions _configurationAndStyleToGmapsOptions(
    MapConfiguration configuration, List<gmaps.MapTypeStyle> styles) {
  final gmaps.MapOptions options = gmaps.MapOptions();

  if (configuration.mapType != null) {
    options.mapTypeId = _gmapTypeIDForPluginType(configuration.mapType!);
  }

  final MinMaxZoomPreference? zoomPreference =
      configuration.minMaxZoomPreference;
  if (zoomPreference != null) {
    options
      ..minZoom = zoomPreference.minZoom
      ..maxZoom = zoomPreference.maxZoom;
  }

  if (configuration.cameraTargetBounds != null) {
    // Needs gmaps.MapOptions.restriction and gmaps.MapRestriction
    // see: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.restriction
  }

  if (configuration.zoomControlsEnabled != null) {
    options.zoomControl = configuration.zoomControlsEnabled;
  }

  if (configuration.scrollGesturesEnabled == false ||
      configuration.zoomGesturesEnabled == false) {
    options.gestureHandling = 'none';
  } else {
    options.gestureHandling = 'auto';
  }

  // These don't have any configuration entries, but they seem to be off in the
  // native maps.
  options.mapTypeControl = false;
  options.fullscreenControl = false;
  options.streetViewControl = false;

  options.styles = styles;

  return options;
}

gmaps.MapTypeId _gmapTypeIDForPluginType(MapType type) {
  switch (type) {
    case MapType.satellite:
      return gmaps.MapTypeId.SATELLITE;
    case MapType.terrain:
      return gmaps.MapTypeId.TERRAIN;
    case MapType.hybrid:
      return gmaps.MapTypeId.HYBRID;
    case MapType.normal:
    case MapType.none:
    default:
      return gmaps.MapTypeId.ROADMAP;
  }
}

gmaps.MapOptions _applyInitialPosition(
  CameraPosition initialPosition,
  gmaps.MapOptions options,
) {
  // Adjust the initial position, if passed...
  if (initialPosition != null) {
    options.zoom = initialPosition.zoom;
    options.center = gmaps.LatLng(
        initialPosition.target.latitude, initialPosition.target.longitude);
  }
  return options;
}

// The keys we'd expect to see in a serialized MapTypeStyle JSON object.
final Set<String> _mapStyleKeys = <String>{
  'elementType',
  'featureType',
  'stylers',
};

// Checks if the passed in Map contains some of the _mapStyleKeys.
bool _isJsonMapStyle(Map<String, Object?> value) {
  return _mapStyleKeys.intersection(value.keys.toSet()).isNotEmpty;
}

// Converts an incoming JSON-encoded Style info, into the correct gmaps array.
List<gmaps.MapTypeStyle> _mapStyles(String? mapStyleJson) {
  List<gmaps.MapTypeStyle> styles = <gmaps.MapTypeStyle>[];
  if (mapStyleJson != null) {
    styles = (json.decode(mapStyleJson, reviver: (Object? key, Object? value) {
      if (value is Map && _isJsonMapStyle(value as Map<String, Object?>)) {
        List<Object?> stylers = <Object?>[];
        if (value['stylers'] != null) {
          stylers = (value['stylers']! as List<Object?>)
              .map<Object?>((Object? e) => e != null ? jsify(e) : null)
              .toList();
        }
        return gmaps.MapTypeStyle()
          ..elementType = value['elementType'] as String?
          ..featureType = value['featureType'] as String?
          ..stylers = stylers;
      }
      return value;
    }) as List<Object?>)
        .where((Object? element) => element != null)
        .cast<gmaps.MapTypeStyle>()
        .toList();
    // .toList calls are required so the JS API understands the underlying data structure.
  }
  return styles;
}

gmaps.LatLng _latLngToGmLatLng(LatLng latLng) {
  return gmaps.LatLng(latLng.latitude, latLng.longitude);
}

LatLng _gmLatLngToLatLng(gmaps.LatLng latLng) {
  return LatLng(latLng.lat.toDouble(), latLng.lng.toDouble());
}

LatLngBounds _gmLatLngBoundsTolatLngBounds(gmaps.LatLngBounds latLngBounds) {
  return LatLngBounds(
    southwest: _gmLatLngToLatLng(latLngBounds.southWest),
    northeast: _gmLatLngToLatLng(latLngBounds.northEast),
  );
}

CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) {
  return CameraPosition(
    target: _gmLatLngToLatLng(map.center ?? _nullGmapsLatLng),
    bearing: map.heading?.toDouble() ?? 0,
    tilt: map.tilt?.toDouble() ?? 0,
    zoom: map.zoom?.toDouble() ?? 0,
  );
}

// Convert plugin objects to gmaps.Options objects
// TODO(ditman): Move to their appropriate objects, maybe make them copy constructors?
// Marker.fromMarker(anotherMarker, moreOptions);

gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) {
  final String markerTitle = marker.infoWindow.title ?? '';
  final String markerSnippet = marker.infoWindow.snippet ?? '';

  // If both the title and snippet of an infowindow are empty, we don't really
  // want an infowindow...
  if ((markerTitle.isEmpty) && (markerSnippet.isEmpty)) {
    return null;
  }

  // Add an outer wrapper to the contents of the infowindow, we need it to listen
  // to click events...
  final HtmlElement container = DivElement()
    ..id = 'gmaps-marker-${marker.markerId.value}-infowindow';

  if (markerTitle.isNotEmpty) {
    final HtmlElement title = HeadingElement.h3()
      ..className = 'infowindow-title'
      ..innerText = markerTitle;
    container.children.add(title);
  }
  if (markerSnippet.isNotEmpty) {
    final HtmlElement snippet = DivElement()
      ..className = 'infowindow-snippet'
      // `sanitizeHtml` is used to clean the (potential) user input from (potential)
      // XSS attacks through the contents of the marker InfoWindow.
      // See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html
      // See: b/159137885, b/159598165
      // The NodeTreeSanitizer.trusted just tells setInnerHtml to leave the output
      // of `sanitizeHtml` untouched.
      // ignore: unsafe_html
      ..setInnerHtml(
        sanitizeHtml(markerSnippet),
        treeSanitizer: NodeTreeSanitizer.trusted,
      );
    container.children.add(snippet);
  }

  return gmaps.InfoWindowOptions()
    ..content = container
    ..zIndex = marker.zIndex;
  // TODO(ditman): Compute the pixelOffset of the infoWindow, from the size of the Marker,
  // and the marker.infoWindow.anchor property.
}

// Attempts to extract a [gmaps.Size] from `iconConfig[sizeIndex]`.
gmaps.Size? _gmSizeFromIconConfig(List<Object?> iconConfig, int sizeIndex) {
  gmaps.Size? size;
  if (iconConfig.length >= sizeIndex + 1) {
    final List<Object?>? rawIconSize = iconConfig[sizeIndex] as List<Object?>?;
    if (rawIconSize != null) {
      size = gmaps.Size(
        rawIconSize[0] as num?,
        rawIconSize[1] as num?,
      );
    }
  }
  return size;
}

// Converts a [BitmapDescriptor] into a [gmaps.Icon] that can be used in Markers.
gmaps.Icon? _gmIconFromBitmapDescriptor(BitmapDescriptor bitmapDescriptor) {
  final List<Object?> iconConfig = bitmapDescriptor.toJson() as List<Object?>;

  gmaps.Icon? icon;

  if (iconConfig != null) {
    if (iconConfig[0] == 'fromAssetImage') {
      assert(iconConfig.length >= 2);
      // iconConfig[2] contains the DPIs of the screen, but that information is
      // already encoded in the iconConfig[1]
      icon = gmaps.Icon()
        ..url = ui.webOnlyAssetManager.getAssetUrl(iconConfig[1]! as String);

      final gmaps.Size? size = _gmSizeFromIconConfig(iconConfig, 3);
      if (size != null) {
        icon
          ..size = size
          ..scaledSize = size;
      }
    } else if (iconConfig[0] == 'fromBytes') {
      // Grab the bytes, and put them into a blob
      final List<int> bytes = iconConfig[1]! as List<int>;
      // Create a Blob from bytes, but let the browser figure out the encoding
      final Blob blob = Blob(<dynamic>[bytes]);
      icon = gmaps.Icon()..url = Url.createObjectUrlFromBlob(blob);

      final gmaps.Size? size = _gmSizeFromIconConfig(iconConfig, 2);
      if (size != null) {
        icon
          ..size = size
          ..scaledSize = size;
      }
    }
  }

  return icon;
}

// Computes the options for a new [gmaps.Marker] from an incoming set of options
// [marker], and the existing marker registered with the map: [currentMarker].
// Preserves the position from the [currentMarker], if set.
gmaps.MarkerOptions _markerOptionsFromMarker(
  Marker marker,
  gmaps.Marker? currentMarker,
) {
  return gmaps.MarkerOptions()
    ..position = currentMarker?.position ??
        gmaps.LatLng(
          marker.position.latitude,
          marker.position.longitude,
        )
    ..title = sanitizeHtml(marker.infoWindow.title ?? '')
    ..zIndex = marker.zIndex
    ..visible = marker.visible
    ..opacity = marker.alpha
    ..draggable = marker.draggable
    ..icon = _gmIconFromBitmapDescriptor(marker.icon);
  // TODO(ditman): Compute anchor properly, otherwise infowindows attach to the wrong spot.
  // Flat and Rotation are not supported directly on the web.
}

gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) {
  final gmaps.CircleOptions circleOptions = gmaps.CircleOptions()
    ..strokeColor = _getCssColor(circle.strokeColor)
    ..strokeOpacity = _getCssOpacity(circle.strokeColor)
    ..strokeWeight = circle.strokeWidth
    ..fillColor = _getCssColor(circle.fillColor)
    ..fillOpacity = _getCssOpacity(circle.fillColor)
    ..center = gmaps.LatLng(circle.center.latitude, circle.center.longitude)
    ..radius = circle.radius
    ..visible = circle.visible
    ..zIndex = circle.zIndex;
  return circleOptions;
}

gmaps.PolygonOptions _polygonOptionsFromPolygon(
    gmaps.GMap googleMap, Polygon polygon) {
  // Convert all points to GmLatLng
  final List<gmaps.LatLng> path =
      polygon.points.map(_latLngToGmLatLng).toList();

  final bool isClockwisePolygon = _isPolygonClockwise(path);

  final List<List<gmaps.LatLng>> paths = <List<gmaps.LatLng>>[path];

  for (int i = 0; i < polygon.holes.length; i++) {
    final List<LatLng> hole = polygon.holes[i];
    final List<gmaps.LatLng> correctHole = _ensureHoleHasReverseWinding(
      hole,
      isClockwisePolygon,
      holeId: i,
      polygonId: polygon.polygonId,
    );
    paths.add(correctHole);
  }

  return gmaps.PolygonOptions()
    ..paths = paths
    ..strokeColor = _getCssColor(polygon.strokeColor)
    ..strokeOpacity = _getCssOpacity(polygon.strokeColor)
    ..strokeWeight = polygon.strokeWidth
    ..fillColor = _getCssColor(polygon.fillColor)
    ..fillOpacity = _getCssOpacity(polygon.fillColor)
    ..visible = polygon.visible
    ..zIndex = polygon.zIndex
    ..geodesic = polygon.geodesic;
}

List<gmaps.LatLng> _ensureHoleHasReverseWinding(
  List<LatLng> hole,
  bool polyIsClockwise, {
  required int holeId,
  required PolygonId polygonId,
}) {
  List<gmaps.LatLng> holePath = hole.map(_latLngToGmLatLng).toList();
  final bool holeIsClockwise = _isPolygonClockwise(holePath);

  if (holeIsClockwise == polyIsClockwise) {
    holePath = holePath.reversed.toList();
    if (kDebugMode) {
      print('Hole [$holeId] in Polygon [${polygonId.value}] has been reversed.'
          ' Ensure holes in polygons are "wound in the opposite direction to the outer path."'
          ' More info: https://github.com/flutter/flutter/issues/74096');
    }
  }

  return holePath;
}

/// Calculates the direction of a given Polygon
/// based on: https://stackoverflow.com/a/1165943
///
/// returns [true] if clockwise [false] if counterclockwise
///
/// This method expects that the incoming [path] is a `List` of well-formed,
/// non-null [gmaps.LatLng] objects.
///
/// Currently, this method is only called from [_polygonOptionsFromPolygon], and
/// the `path` is a transformed version of [Polygon.points] or each of the
/// [Polygon.holes], guaranteeing that `lat` and `lng` can be accessed with `!`.
bool _isPolygonClockwise(List<gmaps.LatLng> path) {
  double direction = 0.0;
  for (int i = 0; i < path.length; i++) {
    direction = direction +
        ((path[(i + 1) % path.length].lat - path[i].lat) *
            (path[(i + 1) % path.length].lng + path[i].lng));
  }
  return direction >= 0;
}

gmaps.PolylineOptions _polylineOptionsFromPolyline(
    gmaps.GMap googleMap, Polyline polyline) {
  final List<gmaps.LatLng> paths =
      polyline.points.map(_latLngToGmLatLng).toList();

  return gmaps.PolylineOptions()
    ..path = paths
    ..strokeWeight = polyline.width
    ..strokeColor = _getCssColor(polyline.color)
    ..strokeOpacity = _getCssOpacity(polyline.color)
    ..visible = polyline.visible
    ..zIndex = polyline.zIndex
    ..geodesic = polyline.geodesic;
//  this.endCap = Cap.buttCap,
//  this.jointType = JointType.mitered,
//  this.patterns = const <PatternItem>[],
//  this.startCap = Cap.buttCap,
//  this.width = 10,
}

// Translates a [CameraUpdate] into operations on a [gmaps.GMap].
void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) {
  // Casts [value] to a JSON dictionary (string -> nullable object). [value]
  // must be a non-null JSON dictionary.
  Map<String, Object?> asJsonObject(dynamic value) {
    return (value as Map<Object?, Object?>).cast<String, Object?>();
  }

  // Casts [value] to a JSON list. [value] must be a non-null JSON list.
  List<Object?> asJsonList(dynamic value) {
    return value as List<Object?>;
  }

  final List<dynamic> json = update.toJson() as List<dynamic>;
  switch (json[0]) {
    case 'newCameraPosition':
      final Map<String, Object?> position = asJsonObject(json[1]);
      final List<Object?> latLng = asJsonList(position['target']);
      map.heading = position['bearing'] as num?;
      map.zoom = position['zoom'] as num?;
      map.panTo(
        gmaps.LatLng(latLng[0] as num?, latLng[1] as num?),
      );
      map.tilt = position['tilt'] as num?;
      break;
    case 'newLatLng':
      final List<Object?> latLng = asJsonList(json[1]);
      map.panTo(gmaps.LatLng(latLng[0] as num?, latLng[1] as num?));
      break;
    case 'newLatLngZoom':
      final List<Object?> latLng = asJsonList(json[1]);
      map.zoom = json[2] as num?;
      map.panTo(gmaps.LatLng(latLng[0] as num?, latLng[1] as num?));
      break;
    case 'newLatLngBounds':
      final List<Object?> latLngPair = asJsonList(json[1]);
      final List<Object?> latLng1 = asJsonList(latLngPair[0]);
      final List<Object?> latLng2 = asJsonList(latLngPair[1]);
      map.fitBounds(
        gmaps.LatLngBounds(
          gmaps.LatLng(latLng1[0] as num?, latLng1[1] as num?),
          gmaps.LatLng(latLng2[0] as num?, latLng2[1] as num?),
        ),
      );
      // padding = json[2];
      // Needs package:google_maps ^4.0.0 to adjust the padding in fitBounds
      break;
    case 'scrollBy':
      map.panBy(json[1] as num?, json[2] as num?);
      break;
    case 'zoomBy':
      gmaps.LatLng? focusLatLng;
      final double zoomDelta = json[1] as double? ?? 0;
      // Web only supports integer changes...
      final int newZoomDelta =
          zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil();
      if (json.length == 3) {
        final List<Object?> latLng = asJsonList(json[2]);
        // With focus
        try {
          focusLatLng =
              _pixelToLatLng(map, latLng[0]! as int, latLng[1]! as int);
        } catch (e) {
          // https://github.com/a14n/dart-google-maps/issues/87
          // print('Error computing new focus LatLng. JS Error: ' + e.toString());
        }
      }
      map.zoom = (map.zoom ?? 0) + newZoomDelta;
      if (focusLatLng != null) {
        map.panTo(focusLatLng);
      }
      break;
    case 'zoomIn':
      map.zoom = (map.zoom ?? 0) + 1;
      break;
    case 'zoomOut':
      map.zoom = (map.zoom ?? 0) - 1;
      break;
    case 'zoomTo':
      map.zoom = json[1] as num?;
      break;
    default:
      throw UnimplementedError('Unimplemented CameraMove: ${json[0]}.');
  }
}

// original JS by: Byron Singh (https://stackoverflow.com/a/30541162)
gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) {
  final gmaps.LatLngBounds? bounds = map.bounds;
  final gmaps.Projection? projection = map.projection;
  final num? zoom = map.zoom;

  assert(
      bounds != null, 'Map Bounds required to compute LatLng of screen x/y.');
  assert(projection != null,
      'Map Projection required to compute LatLng of screen x/y');
  assert(zoom != null,
      'Current map zoom level required to compute LatLng of screen x/y');

  final gmaps.LatLng ne = bounds!.northEast;
  final gmaps.LatLng sw = bounds.southWest;

  final gmaps.Point topRight = projection!.fromLatLngToPoint!(ne)!;
  final gmaps.Point bottomLeft = projection.fromLatLngToPoint!(sw)!;

  final int scale = 1 << (zoom!.toInt()); // 2 ^ zoom

  final gmaps.Point point =
      gmaps.Point((x / scale) + bottomLeft.x!, (y / scale) + topRight.y!);

  return projection.fromPointToLatLng!(point)!;
}
