(function ($, Drupal, drupalSettings, once) {
  var DataLayer = window.dataLayer || [];
  var phone_hash = drupalSettings.user_phone ?? '';

  Drupal.behaviors.map = {
    attach: function (context, settings) {

      // Initialize and add the map
      const maps = once('initMap', '.map', context);
      google.maps.visualRefresh = true;
      maps.forEach(function () {
        var mapWrapper = $(this);
        var map;
        var markerCluster;
        var markers = [];
        var mapSettings = {};
        let locations = drupalSettings.locations !== undefined ? drupalSettings.locations : [];
        let icons = drupalSettings.icons ?? [];
        let map_id = drupalSettings.map_id ?? '';
        let use_clusters = drupalSettings.use_clusters ?? [];
        let show_categories = drupalSettings.show_categories ?? [];
        let show_list_counter = drupalSettings.show_list_counter ?? [];
        let show_directions = drupalSettings.show_directions ?? [];
        let show_share = drupalSettings.show_share ?? [];
        let use_numbers = drupalSettings.use_numbers ?? [];
        let use_datalayer = drupalSettings.use_datalayer ?? [];
        let use_select_poc = drupalSettings.use_select_poc ?? [];
        let use_select_poc_link = drupalSettings.use_select_poc_link ?? [];
        let filtered_locations = [];
        mapSettings.default_zoom = 7;
        // var mapSettings = drupalSettings.default_map_settings;

        var infoWindow = {};
        var bounds = {}

        setTimeout(function () {
          initialize();
        }, 100);

        function initialize(lat, lon, defaultZoom = '') {
          infoWindow = new google.maps.InfoWindow({
            content: '',
          });

          bounds = new google.maps.LatLngBounds();

          let styles = [
            {
              "featureType": "administrative",
              "elementType": "all",
              "stylers": [
                {
                  "visibility": "simplified"
                }
              ]
            },
            {
              "featureType": "landscape",
              "elementType": "all",
              "stylers": [
                {
                  "visibility": "on"
                }
              ]
            },
            {
              "featureType": "poi",
              "elementType": "all",
              "stylers": [
                {
                  "visibility": "off"
                }
              ]
            },
            {
              "featureType": "transit",
              "elementType": "all",
              "stylers": [
                {
                  "visibility": "off"
                }
              ]
            }
          ];
          let default_lat = lat ? lat : 53.3229432;
          let default_lon = lon ? lon : -7.7483999;
          let initZoom = defaultZoom !== '' ? +defaultZoom : +mapSettings.default_zoom;


          map = new google.maps.Map(
            document.getElementById('map'), {
              center: new google.maps.LatLng(default_lat, default_lon),
              zoom: map !== undefined ? map.getZoom() : initZoom,
              mapTypeId: google.maps.MapTypeId.ROADMAP,
              mapId: map_id,
              //mapId: 'c4c116ea09005722',
              streetViewControl: false,
              //gestureHandling: "greedy",
              fullscreenControl: true,
              styles: styles
            });

          addYourLocationButton(map);
          requestPocs();

          map.addListener("click", function (event) {
            infoWindow.close();
            $('#map-info-panel .close').click();

            if (use_datalayer) {
              DataLayer.push({
                'event': 'GAEvent',
                'event_category': 'Map',
                'event_action': 'CloseInfoWindow',
                'event_label': "Close", // example: Know More
                'interaction': 'true',
                'component_name': 'Google maps close infowindow', // example:knowmore_button
                'element_text': 'Google maps close infowindow', // example: Know More
                'user_id_phone_hash': phone_hash
              });
            }
          });
        }

        // Make Ajax call to receive list of pocs.
        function requestPocs() {
          let pocId = 'active';
          if (locations) {
            let activePromise = new Promise((resolve, reject) => {
              renderLocationsOnMap(locations, pocId);
              renderListItem(locations);
              if (drupalSettings.use_filters != undefined && drupalSettings.use_filters) {
                let categories = renderCategories();
              }
            })
          }
        }

        /**
         * Render List Item.
         * @param locations
         * @returns {string}
         */
        function renderListItem(locations) {
          let element = '';
          $('.place-list-wrapper').html('');
          let number = '';
          for (let i = 0; i < locations.length; i++) {
            let location = locations[i];

            let info = JSON.parse(location.full_info);
            let category = '';
            if (show_categories) {
              let category_class = location.category.toLowerCase().split(' ').join('-');
              category = ' | <span class="' + category_class + '">' + location.category + '</span>';
            }
            let buttons_start = '';
            let buttons_end = '';
            if (show_directions || show_share) {
              buttons_start = '<div class="buttons">';
              buttons_end = '</div>';
            }
            let direction_button = '';
            if (show_directions) {
              direction_button = '<a class="direction-button" href="https://www.google.com/maps/dir/Current+Location/' + location.lat + ',' + location.lon + '" target="_blank">' + Drupal.t('Get Directions') + '</a>';
            }

            let share_button = '';
            if (show_share) {
              share_button = ' <a  href="#" class="share-offer-link" data-bs-toggle="modal" data-bs-target="#shareModal" data-place-title="' + location.title + '">' +
                Drupal.t('Share') +
                '</a>';
            }

            let poc_link = '';
            if (use_select_poc) {
              poc_link =  ' <a  href="'+use_select_poc_link+'?pocid='+location.id+'" class="select-poc-link" >' +
                Drupal.t('Select POC') +
                '</a>';
            }

            if (use_numbers) {
              number = (i + 1) + '. ';
            }
            element += '<div class="place-wrapper" data-place-title="' + location.title + '" data-place-id="' + location.place_id + '">' +
              '<h2>' + number + location.title + category + '</h2>' +
              '<p>' + info.formatted_address + '</p>' +
              buttons_start +
              direction_button +
              share_button +
              poc_link +
              buttons_end +
              '</div>' +
              '</div>';

          }

          if (!element.length) {
            element = '<h3>' + Drupal.t("Place has not been found.") + '</h3>';
          }

          if (drupalSettings.no_api_key === true) {
            element = '<h3>' + Drupal.t("No Google API key provided. Please contact site admin to provide it.") + '</h3>';
          }
          $('.place-list-wrapper').append(element);

          if (show_list_counter) {
            $('.total-count-placeholder').html('<div class="total-count">' + Drupal.formatPlural(locations.length, '<span>1</span> bar found', '<span> @count </span> bars found') + '</div>');
          }

          return element;
        }

        // Render Info template.
        function renderInfo(place) {

          let full_info =  JSON.parse(place.full_info);
          console.log(full_info);
          let info_content = '';
          info_content = '<h2>' + place.title + '</h2>';
          info_content += '<div class="address"><span class="icon"></span>' + full_info.formatted_address + '</div><br />';
          if (show_directions || show_share) {
            info_content += '<div class="buttons">';
          }
          if (show_directions) {
            info_content += '<div>' + '<a class="direction-button" href="https://www.google.com/maps/dir/Current+Location/' + place.lat + ',' + place.lon + '" target="_blank">' + Drupal.t('Get Directions') + '</a></div>';
          }
          if (show_share) {
            info_content +=
              '<a href="#" class="share-offer-link" data-bs-toggle="modal" data-bs-target="#shareModal" data-place-title="' + place.title + '">' +
              'Share' +
              '</a>';
          }
          if (use_select_poc) {
            info_content +=
              '<a  href="'+use_select_poc_link+'?pocid='+place.id+'" class="select-poc-link" >' +
              Drupal.t('Select POC') +
              '</a>';
          }
          if (show_directions || show_share) {
            info_content += '</div>';
          }
          return info_content;
        }


        // Render Map. Put all points.
        function renderLocationsOnMap(locations) {
          let places = [];
          bounds = new google.maps.LatLngBounds();
          for (let i = 0; i < locations.length; i++) {
            places.push(renderMarker(locations[i]));
            var geoCode = new google.maps.LatLng(locations[i]['lat'], locations[i]['lon']);
            bounds.extend(geoCode);
            openSharedPlace(locations[i]);
          }
          map.fitBounds(bounds);

          // setTimeout(function () {
          //   let zoom = map.getZoom();
          //   map.setZoom(+zoom + 1);
          // }, 100);

          // If use clusters option is enabled.
          if (use_clusters) {
            if (markerCluster) {
              markerCluster.setIgnoreHidden(true);
              markerCluster.repaint();
            }

            markerCluster = new MarkerClusterer(map, places, {
              imagePath: 'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m',
              ignoreHidden: true,
              maxZoom: 12,
              zoomOnClick: true,
            });
          }
        }

        // Make markers invisible.
        function clearMarkers() {
          for (let i = 0; i < markers.length; i++) {
            //marker.setVisible(showMarker);
            markers[i].marker.setVisible(false);
          }
          //scrollToMap();
        }

        /**
         * Render Map. Pure Google APi methods.
         * @param place
         * @param poc_type
         */
        let showMarker = '';

        function renderMarker(place, poc_type = 'active') {
          let icon_path = '';

          if (drupalSettings.default_icon !== undefined && drupalSettings.default_icon.length) {
            icon_path = drupalSettings.default_icon;
          }

          if (drupalSettings.use_categories != undefined && drupalSettings.use_categories) {
            let categories = place.category;
            categories = categories.split(',');
            categories = categories.map(function (item) {
              return item.toLowerCase();
            })

            if (categories.length && drupalSettings.icons[categories[0]] !== undefined) {
              icon_path = drupalSettings.icons[categories[0]].file;
            }
          }

          let lat = +place.lat;
          let lon = +place.lon;
          let zoom = map.getZoom()
          var marker;

          if (icon_path !== "") {
            marker = new google.maps.Marker({
              map: map,
              position: new google.maps.LatLng({lat: lat, lng: lon}),
              title: place.title,
              icon: {
                url: icon_path ?? "",
                scaledSize: new google.maps.Size(30, 36), // scaled size
              },
            });
          } else {
            marker = new google.maps.Marker({
              map: map,
              position: new google.maps.LatLng({lat: lat, lng: lon}),
              title: place.title,
            });
          }
          //showMarker = (poc_type === 'active') || (zoom >= +mapSettings.na_zoom);
          showMarker = true;
          marker.setVisible(showMarker);
          bounds.extend(marker.position);

          markers.push({'marker': marker, 'poc_type': poc_type});

          google.maps.event.addListener(marker, 'click', function () {
            //let user_name = drupalSettings.user_name;
            infoWindow.setContent(renderInfo(place));
            infoWindow.open(map, marker);
            if (use_datalayer) {
              DataLayer.push({
                'event': 'GAEvent',
                'event_category': 'Map',
                'event_action': 'OpenInfoWindow',
                'event_label': "Open",
                'interaction': 'true',
                'component_name': 'open_active_poc_info_window',
                'element_text': 'Open Active POC Info Window',
                'product': place.title, // product description
                'sku': place.poc_id, // product sku
                'user_id_phone_hash': phone_hash
              });
            }


          });
          return marker;
        }

        $('.clear-search').on('click', function () {
          let locations = drupalSettings.locations !== undefined ? drupalSettings.locations : [];
          clearMarkers();
          renderLocationsOnMap(locations);
          renderListItem(locations);
          infoWindow.close();
          $('.place-search-form input').val('');
        })

        $('.search_locations').on('click', function () {
          $('.place-search-form').submit();
        })

        /**
         * Submit serach form.
         */
        $('.place-search-form').on('submit', function (e) {
          e.preventDefault();
          filtered_locations = [];
          let search = $(this).find('input').val().toLowerCase();
          let locations = drupalSettings.locations !== undefined ? drupalSettings.locations : [];
          let search_values = search.split(' ');
          let search_result = locations.filter(function (location) {
            for (let i = 0; i < search_values.length; i++) {
              let search = search_values[i];
              if (search.length && search !== "") {
                let place_id = '';
                let title = location.title.toLowerCase().includes(search);
                //let place_id = location.place_id.toLowerCase().includes(search);
                let info =  JSON.parse(location.full_info)
                let addr = info.formatted_address.toLowerCase().includes(search);

                if (title /*|| place_id*/ || addr) {
                  filtered_locations.push(location);
                  return location;
                }
              }
              else {
                return location;
              }
              return false;
            }
          });
          clearMarkers();

          renderLocationsOnMap(search_result);
          renderListItem(search_result);
          infoWindow.close();
        })

        $('body', context).on('click', '.location-category-filter', function () {
          filtered_locations = [];
          //scrollToMap();
          let search_result = [];
          let locations = drupalSettings.locations !== undefined ? drupalSettings.locations : [];
          let has_selected_category = [];
          $('.location-category-filter').each(function () {
            if ($(this).is(':checked')) {
              has_selected_category.push(true);
              let selected_category = $(this).attr('id').toLowerCase();
              search_result.push(locations.filter(function (location) {
                  //location = location[0];
                  let location_category = location.category.toLowerCase();
                  return location_category.includes(selected_category) ? location : false;
                })
              );
            }
          });


          if (search_result && has_selected_category.length) {
            search_result.forEach(function (item) {
              item.map(function (element) {
                filtered_locations.push(element);
              })
            })
          }
          if (!has_selected_category.length) {
            filtered_locations = locations;
          }
          clearMarkers();
          renderLocationsOnMap(filtered_locations);
          renderListItem(filtered_locations);
        })

        /**
         * Open infoWindow on list item click.
         */
        $('body', context).on('click', '.place-wrapper', function () {
          clickPlaceItemList($(this));
          $(this).addClass('active').siblings().removeClass('active');
        })

        /**
         * Render filters
         */
        function renderCategories() {

          if (drupalSettings.icons !== undefined) {
            let icons = drupalSettings.icons;

            let $categories = `<ul class="d-flex justify-content-evenly">`;
            for (const [key, value] of Object.entries(icons)) {

              let translated_key = value.translation;
              let title = value.title;
              let file = value.file;
              $categories += `<li class="d-flex flex-column justify-content-center">
<label for="${title}"><img width="25px" height="auto" src="${file}"/><span>${translated_key}</span>
</label>

<input type="checkbox" class="location-category-filter" id="${title}" name="${title}"/></li>`;
            }
            $categories += `</ul>`;

            $('.location-filters-wrapper').append($categories);
          }
        }


        /**
         * Click list item.
         * @param element
         */
        function clickPlaceItemList(element) {
          let title = element.data('place-title');
          let place_id = element.data('place-id');
          let clicked = locations.filter(function (item) {
            if (place_id === item.place_id) {
              return item;
            }
          })

          infoWindow.close();

          let clicked_marker = markers.filter(function (item) {
            if (title === item.marker.title) {
              return item;
            }
          })
          let marker = clicked_marker[0].marker;
          infoWindow.setContent(renderInfo(clicked[0]));
          infoWindow.open(map, marker);

          google.maps.event.trigger(marker, 'click', {
              latLng: new google.maps.LatLng(0, 0),
            },
            map.panTo(marker.getPosition()),
          );
          setTimeout(function () {
            map.setZoom(15);
            //markerCluster.clear();
          }, 100);
        }

        function getLocationParam() {
          let title = '';
          let url = window.location.href;
          let url_parts = url.split('?');
          let params = url_parts[1];
          if (params !== undefined) {
            let params_parts = params.split('&');
            params_parts.map(function (item) {
              let param = item.split('=');
              if (param[0] === 'location') {
                title = param[1];
              }
            });
          }
          return title;
        }

        // function scrollToMap() {
        //   let target = $('#map');
        //   $('html,body').animate({
        //     scrollTop: target.offset().top
        //   }, 1000);
        // }
        function openSharedPlace(place) {
          let title = getLocationParam();
          if (decodeURI(title) === place.title) {
            //scrollToMap();
            markers.map(function (marker) {
              if (marker.marker.title === place.title) {
                google.maps.event.trigger(marker.marker, 'click', {
                    latLng: new google.maps.LatLng(0, 0),
                  },
                  map.panTo(marker.marker.getPosition()),
                );
                setTimeout(function () {
                  map.setZoom(18);
                }, 100)
              }
            });
          }
        }

        /**
         * Re
         */
        function requestUserPosition() {
          if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
              (position) => {
                initialize(position.coords.latitude, position.coords.longitude, 15);
              },
              () => {
                setTimeout(function () {
                  initialize();
                }, 100);
                if (use_datalayer) {
                  DataLayer.push({
                    'event': 'GAEvent',
                    'event_category': 'Map',
                    'event_action': 'Sucess',
                    'event_label': 'AllowGeolocation',
                    'interaction': 'true',
                    'component_name': 'Allow Geolocation Button',
                    'user_id_phone_hash': phone_hash
                  });
                }
                //handleLocationError(true, infoWindow, map.getCenter());
              }
            );
          } else {
            setTimeout(function () {
              initialize();
            }, 100);
            if (use_datalayer) {
              DataLayer.push({
                'event': 'GAEvent',
                'event_category': 'Map',
                'event_action': 'Decline',
                'event_label': 'DeclineGeolocation',
                'interaction': 'true',
                'component_name': 'Decline Geolocation Button',
                'user_id_phone_hash': phone_hash
              });
            }
            // Browser doesn't support Geolocation
            handleLocationError(false, infoWindow, map.getCenter());
          }
        }

        function handleLocationError(browserHasGeolocation, infoWindow, pos) {
          infoWindow.setPosition(pos);
          infoWindow.setContent(
            browserHasGeolocation
              ? "Error: The Geolocation service failed."
              : "Error: Your browser doesn't support geolocation."
          );
          infoWindow.open(map);
        }
      })

      function addYourLocationButton(map) {
        var controlDiv = document.createElement('div');

        var firstChild = document.createElement('button');
        firstChild.style.backgroundColor = '#fff';
        firstChild.style.border = 'none';
        firstChild.style.outline = 'none';
        firstChild.style.width = '28px';
        firstChild.style.height = '28px';
        firstChild.style.borderRadius = '2px';
        firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)';
        firstChild.style.cursor = 'pointer';
        firstChild.style.marginRight = '10px';
        firstChild.style.padding = '0';
        firstChild.title = 'Your Location';
        controlDiv.appendChild(firstChild);

        var secondChild = document.createElement('div');
        secondChild.style.margin = '5px';
        secondChild.style.width = '18px';
        secondChild.style.height = '18px';
        secondChild.style.backgroundImage = 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-2x.png)';
        secondChild.style.backgroundSize = '180px 18px';
        secondChild.style.backgroundPosition = '0 0';
        secondChild.style.backgroundRepeat = 'no-repeat';
        firstChild.appendChild(secondChild);

        google.maps.event.addListener(map, 'center_changed', function () {
          secondChild.style['background-position'] = '0 0';
        });

        firstChild.addEventListener('click', function () {
          if (use_datalayer) {
            DataLayer.push({
              'event': 'GAEvent',
              'event_category': 'Content',
              'event_action': 'Content',
              'event_label': 'Show My Location Button', // example: Know More
              'interaction': 'true',
              'component_name': 'my_location_button', // example:knowmore_button
              'element_text': 'Get My Location', // example: Know More
              'user_id_phone_hash': phone_hash
            });
          }
          var imgX = '0',
            animationInterval = setInterval(function () {
              imgX = imgX === '-18' ? '0' : '-18';
              secondChild.style['background-position'] = imgX + 'px 0';
            }, 500);

          //if(navigator.geolocation) {
          navigator.permissions.query({name: 'geolocation'})
            .then(
              function () {
                navigator.geolocation.getCurrentPosition(function (position) {
                  var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                  map.setCenter(latlng);
                  map.setZoom(15);
                  clearInterval(animationInterval);
                  secondChild.style['background-position'] = '-144px 0';
                })
              }
            )
        });

        controlDiv.index = 1;
        map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv);
      }


    }
  }

  Drupal.behaviors.share_button = {
    attach: function (context, settings) {

      $('#shareModal').on('shown.bs.modal', function (e) {
        var placeTitle = $(e.relatedTarget).data('place-title');
        $('#share-link').val(window.location.origin + window.location.pathname + '?location=' + placeTitle);
      });

      const maps = once('copy', '.share-container button#button-addon2', context);
      maps.forEach(function () {
        // Get the text field
        $('button#button-addon2').on('click', function () {
          var copyText = document.getElementById("share-link");

          // Select the text field
          copyText.select();
          copyText.setSelectionRange(0, 99999); // For mobile devices

          // Copy the text inside the text field
          navigator.clipboard.writeText(copyText.value);

          // Alert the copied text
          $(this).addClass('copied').val(Drupal.t('Copied')).find('.label').text(Drupal.t('Copied'));
          // DataLayer.push({
          //   'event': 'GAEvent',
          //   'event_category': 'Content',
          //   'event_action': 'Content',
          //   'event_label': "CopyLink", // example: Know More
          //   'interaction': 'true',
          //   'component_name': 'CopyLinkButton', // example:knowmore_button
          //   'element_text': 'Copy', // example: Know More
          //   'user_id_phone_hash': phone_hash
          // });
        });
      });

      const maps2 = once('copy2', '.share-container button#share-button', context);
      maps2.forEach(function () {
        // DataLayer.push({
        //   'event': 'GAEvent',
        //   'event_category': 'Content',
        //   'event_action': 'Content',
        //   'event_label': "ShareLink", // example: Know More
        //   'interaction': 'true',
        //   'component_name': 'ShareLinkButton', // example:knowmore_button
        //   'element_text': 'Share', // example: Know More
        //   'user_id_phone_hash': phone_hash
        // });

        $('button#share-button').on('click', function () {
          if (navigator.share) {
            var copyText = $("#share-link");
            navigator.share({
              title: Drupal.t('Corona.de shared content title.'),
              text: Drupal.t('Corona.de shared content text.'),
              url: copyText.val(),
            })
              .then(() => console.log('Successful share'))
              .catch((error) => console.log('Error sharing', error));
          } else {
            $('.share-container button#share-button').hide().before(Drupal.t('<p>Share not supported on this browser, do it the old way</p>'));
            //console.log('Share not supported on this browser, do it the old way.');
          }
        });
      })

      let switchButtons = once('switchButton', '.switch-button', context);
      switchButtons.forEach(function (button) {
        $(button).on('click', function () {
          $('.map-container').removeClass('d-none');
          $('.list-column').removeClass('d-none');
          let target = $(this).data('target');
          $(this).data('target', $(this).data('target') === 'map' ? 'list' : 'map');
          target === 'map' ? $('.map-container').addClass('d-none') : $('.list-column').addClass('d-none');
        });
      });

    }
  }


})(jQuery, Drupal, drupalSettings, once);
