import 'gmap3'
import selectric from 'selectric'
import PerfectScrollbar from 'perfect-scrollbar/dist/perfect-scrollbar.esm.js'

$ = jQuery
$.gmap3(false)

const loadGoogleMapsAPI = require('load-google-maps-api')

const themeGmap = [
	{
		featureType: 'administrative',
		elementType: 'all',
		stylers: [
			{
				saturation: '-100',
			},
		],
	},
	{
		featureType: 'administrative.province',
		elementType: 'all',
		stylers: [
			{
				visibility: 'off',
			},
		],
	},
	{
		featureType: 'landscape',
		elementType: 'all',
		stylers: [
			{
				saturation: -100,
			},
			{
				lightness: 65,
			},
			{
				visibility: 'on',
			},
		],
	},
	{
		featureType: 'poi',
		elementType: 'all',
		stylers: [
			{
				saturation: -100,
			},
			{
				lightness: '50',
			},
			{
				visibility: 'off',
			},
		],
	},
	{
		featureType: 'road',
		elementType: 'all',
		stylers: [
			{
				saturation: '-100',
			},
		],
	},
	{
		featureType: 'road.highway',
		elementType: 'all',
		stylers: [
			{
				visibility: 'simplified',
			},
		],
	},
	{
		featureType: 'road.arterial',
		elementType: 'all',
		stylers: [
			{
				lightness: '30',
			},
		],
	},
	{
		featureType: 'road.local',
		elementType: 'all',
		stylers: [
			{
				lightness: '40',
			},
		],
	},
	{
		featureType: 'transit',
		elementType: 'all',
		stylers: [
			{
				saturation: -100,
			},
			{
				visibility: 'simplified',
			},
		],
	},
	{
		featureType: 'water',
		elementType: 'geometry',
		stylers: [
			{
				hue: '#ffff00',
			},
			{
				lightness: -25,
			},
			{
				saturation: -97,
			},
		],
	},
	{
		featureType: 'water',
		elementType: 'labels',
		stylers: [
			{
				lightness: -25,
			},
			{
				saturation: -100,
			},
		],
	},
]

let _mapActive = false
let _wsModalOpened = false
let _initGetMarkersByBounds = false
let _loadingGetMarkersByBounds = false
let _sl

class StoreLocator {
	constructor(el, map) {
		// console.log('StoreLocator :: ', el, map)
		this.el = el
		this.minZoomLevel = 5
		// this.apiKey = 'AIzaSyCVkAVEqmwrmsxhwU4yrkeMicwLYI_9iFs'
		this.apiKey = 'AIzaSyBAdYQYiI_IpavQl8Nb1JwEDnnDCI3XTbk'
		this._map = null
		this.background = this.el.querySelector('.background-wrapper')

		let self = this
		setTimeout(function () {
			$.get('/wp-content/uploads/stores/stores.json', function (data) {
				window.laup_map_stores = data
				// self._populateMarkersShop();
				// self._renderMarkersShop();
				console.log('stores :: ', window.laup_map_stores)
				self.init()
			})
		}, 1000)
	}

	init() {
		console.log('init')
		this._initBlocWebstores()
		window.addEventListener('resize', this.resize.bind(this))

		// this.markersShop = []
		// this._initMap()

		loadGoogleMapsAPI({
			key: this.apiKey,
			libraries: ['places'],
			language: window.lang || 'fr',
			v: '3.53.13',
		})
			.then((googleMaps) => {
				console.log('googleMaps :: ', googleMaps.version)

				this.markersShop = []
				this._initMap()
			})
			.catch((err) => {
				console.log('error :: loading google maps', err)
			})
	}

	_initMap() {
		console.log('init map', google)
		this.mainSearchInput = document.getElementById('main-search-input')
		this.mainSearchBox = new google.maps.places.Autocomplete(this.mainSearchInput)
		this.resultSearchInput = document.getElementById('result-search-input')
		this.resultSearchBox = new google.maps.places.Autocomplete(this.resultSearchInput)
		this.submitSearchButton = document.getElementById('submitSearchButton')
		this.geocoder = new google.maps.Geocoder()
		document.getElementById('submitSearchButton').addEventListener('click', (event) => {
			this.geocodeAddress(this.mainSearchInput.value)
		})

		console.log('google :: ', google, $('#map'))
		$('#map')
			.gmap3({
				address: 'France',
				zoom: 6,
				minZoom: this.minZoomLevel,
				mapTypeId: 'laup',
				mapTypeControl: false,
				disableDefaultUI: false,
				navigationControl: false,
				scaleControl: true,
				scrollwheel: true,
				streetViewControl: false,
				fullscreenControl: false,
				gestureHandling: 'cooperative',
			})
			.then((map) => {
				console.log('map :: ', map)
				this._map = map
				this._populateMarkersShop()
				this._renderMarkersShop()

				this.mainSearchBox.bindTo('bounds', this._map)
				this.mainSearchBox.addListener('place_changed', (event) => {
					const place = this.mainSearchBox.getPlace()
					this.resultSearchInput.value = this.mainSearchInput.value
					this._gotoPlace(place)
				})
				this.resultSearchBox.bindTo('bounds', this._map)
				this.resultSearchBox.addListener('place_changed', (event) => {
					const place = this.resultSearchBox.getPlace()
					this._gotoPlace(place)
				})

				this.resultStore = this.el.querySelector('.result-search-bloc')
				this.resultStoreContent = this.resultStore.querySelector('.content')
				this.psContentResultStore = new PerfectScrollbar(this.resultStoreContent, {
					handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'],
					suppressScrollX: true,
				})
			})
			.catch((err) => {
				console.log('erreur de chargement')
				console.log(err)
			})
			.on({
				click: (map, event) => {
					this.cluster.markers().forEach((mc) => {
						mc.setOpacity(0.6)
					})
					document.querySelectorAll('.result-search-bloc .content ul li').forEach((item) => {
						item.classList.remove('highlight')
						document.getElementById('results-map-list').classList.remove('list_highlight')
					})
				},
				drag: (map) => {
					this.checkLatitude(map)
				},
				dragend: (map) => {
					this.checkLatitude(map)
				},
				idle: (map) => {
					this.checkLatitude(map)
					let self = this
					if (_loadingGetMarkersByBounds || !_initGetMarkersByBounds) {
						// console.log('WAIIIITTTTIIINNGG')
					} else {
						// console.log('GOOOOOOOOOOOOOOOO')
						_loadingGetMarkersByBounds = true
						this.timeout = setTimeout(function () {
							self._getMarkersByBounds(map)
							_loadingGetMarkersByBounds = false
						}, 400)
					}
				},
				zoom_changed: (map) => {
					this.checkLatitude(map)
				},
				bounds_changed: (map) => {
					const latlng = new google.maps.LatLng(map.getCenter().lat(), map.getCenter().lng())

					this.geocoder.geocode({ latLng: latlng }, function (results, status) {
						if (status == google.maps.GeocoderStatus.OK) {
							if (results[1]) {
								var countryCode = null
								var c, lc, component
								for (var r = 0, rl = results.length; r < rl; r += 1) {
									var result = results[r]

									if (!countryCode && result.types[0] === 'country') {
										countryCode = result.address_components[0].short_name
									}

									if (countryCode) {
										break
									}
								}
								// countryCode = 'US'
								// console.log('countryCode :: ', results)

								if (countryCode != 'US') {
									document.querySelectorAll('#results-map-list .format_us').forEach((item) => {
										countryCode = 'US'
									})
								}

								if (countryCode == 'US') {
									document.getElementById('webStoreUsList').style.display = 'block'
								} else {
									document.getElementById('webStoreUsList').style.display = 'none'
								}
							}
						}
					})
				},
			})
			.styledmaptype('laup', themeGmap, { name: 'laup' })

		this.el.querySelector('.close-map-button').addEventListener('click', (event) => {
			this.closeMap()
		})
	}

	closeMap() {
		this.el.querySelector('.container').classList.remove('hidden')
		this.el.querySelector('.map-container').classList.remove('show')
		// showUIExtra(true);
		// enableSliderContainer();
		_mapActive = false
		// window.removeEventListener('resize', this.resize.bind(this));
		this.currentShopId = null
		document.querySelectorAll('.result-search-bloc .content ul li').forEach((item) => {
			item.classList.remove('highlight')
			document.getElementById('results-map-list').classList.remove('list_highlight')
		})

		this.cluster.markers().forEach((mc) => {
			mc.setOpacity(1)
		})
	}

	geocodeAddress(address) {
		this.geocoder.geocode({ address: address }, (results, status) => {
			if (status == 'OK') {
				this.resultSearchInput.value = this.mainSearchInput.value
				this._gotoPlace(results[0])
			} else {
				console.log('Geocode was not successful for the following reason: ' + status)
			}
		})
	}

	_gotoPlace(place) {
		if (place && place.geometry) {
			_initGetMarkersByBounds = true
			this.currentPlace = place
			this.el.querySelector('.container').classList.add('hidden')
			this.el.querySelector('.map-container').classList.add('show')
			// goToSection(this.el, true, true);
			// showUIExtra(false);
			// disableSliderContainer();
			_mapActive = true
			let radius = 100000
			if (place.types.includes('country')) {
				radius = 500000
			}
			if (place.types.includes('locality') || place.types.includes('postal_code')) {
				radius = 5000
			}
			if (
				place.types.includes('street_address') ||
				place.types.includes('route') ||
				place.types.includes('neighborhood') ||
				place.types.includes('point_of_interest')
			) {
				radius = 1000
			}
			let nbShop = 0
			this.markersShop.forEach((shop, idx) => {
				if (place.geometry.viewport.contains(shop.position)) {
					nbShop++
				}
			})
			if (place.geometry.viewport && nbShop > 0) {
				this._map.fitBounds(place.geometry.viewport)
			} else {
				this._map.setCenter(place.geometry.location)
				// this._map.setZoom(17);
				const searchCircle = new google.maps.Circle({
					strokeColor: '#FF0000',
					strokeOpacity: 0.8,
					strokeWeight: 2,
					fillColor: '#FF0000',
					fillOpacity: 0.35,
					map: this._map,
					center: place.geometry.location,
					radius,
				})
				this._map.fitBounds(searchCircle.getBounds())
				searchCircle.setMap(null)
			}
		}
	}

	_populateMarkersShop() {
		// console.log(window.laup_map_stores.data);
		// console.log('*/*/*/*/*/*/*/*/');
		window.laup_map_stores.data.forEach((shop) => this._processShop(shop))
	}

	_processShop(shop) {
		this._addMarkerShop(shop)
	}

	_addMarkerShop(shop) {
		// console.log(shop.lat);
		// console.log(shop.lng);
		if (shop.lat !== '' && shop.lng !== '') {
			let url = '/wp-content/themes/laurentperrier/dist/assets/img/pin.png?v2'
			let size = new google.maps.Size(32, 42)

			if (window.devicePixelRatio > 1.5) {
				url = '/wp-content/themes/laurentperrier/dist/assets/img/pin@2x.png?v2'
				size = new google.maps.Size(64, 84)
			}

			const icon = {
				url: url,
				anchor: new google.maps.Point(16, 34),
				size: new google.maps.Size(32, 42),
				scaledSize: new google.maps.Size(32, 42),
			}

			const marker = new google.maps.Marker({
				position: new google.maps.LatLng({
					lat: parseFloat(shop.lat),
					lng: parseFloat(shop.lng),
				}),
				id: shop.id + '-marker',
				tag: 'marker-shop',
				options: {
					icon: icon,
					clickable: true,
				},
				data: shop,
			})
			this.markersShop.push(marker)
		}
	}

	_renderMarkersShop() {
		// console.log('RENDER MARKERS SHOPS ', this._map, this.markersShop);

		$('.gmap-container')
			.gmap3()
			.cluster({
				size: 200,
				markers: this.markersShop,
				minimumClusterSize: 5,
				cb: (markers) => {
					if (markers.length > 1) {
						// 1 marker stay unchanged (because cb returns nothing)
						return {
							content: "<div class='cluster'>" + markers.length + '</div>',
							x: -20,
							y: -52,
						}
					}
				},
			})
			.then((cluster) => {
				// console.log(cluster.markers());
				this.cluster = cluster
			})
			.on({
				click: (marker, clusterOverlay, cluster, event) => {
					// console.log('CLICK :: ', marker, clusterOverlay, cluster, event)

					if (marker) {
						marker.setOpacity(1)
						this.currentShopId = marker.data.i
						document.querySelectorAll('.result-search-bloc .content ul li').forEach((item) => {
							item.classList.remove('highlight')
							document.getElementById('results-map-list').classList.remove('list_highlight')
						})
						if (document.getElementById(this.currentShopId)) {
							document.getElementById(this.currentShopId).classList.add('highlight')
							document.getElementById('results-map-list').classList.add('list_highlight')
							this.resultStoreContent.scrollTop = document.getElementById(this.currentShopId).offsetTop
						}
						cluster.markers().forEach((mc) => {
							if (mc !== marker) {
								mc.setOpacity(0.6)
							}
						})
					} else if (clusterOverlay) {
						this.fitBoundsToMarkers(clusterOverlay.markers)
					} else {
					}
				},
			})
			.catch((err) => {
				console.log(err)
			})
	}

	fitBoundsToMarkers(markers) {
		const bounds = new google.maps.LatLngBounds()
		markers.forEach((marker, idx) => {
			bounds.extend(marker.getPosition())
		})
		this._map.fitBounds(bounds)
	}

	_getMarkersByBounds(map, place) {
		const bounds = map.getBounds()
		let count = 0
		const result = []

		this.markersShop.forEach((marker) => {
			if (bounds.contains(marker.position) === true) {
				// console.log(count);
				if (count > 50) {
					return true
				}
				count++
				let dist = -1
				if (this.currentPlace && this.currentPlace.geometry) {
					dist = _getDistanceFromLatLonInKm(
						marker.getPosition().lat(),
						marker.getPosition().lng(),
						this.currentPlace.geometry.location.lat(),
						this.currentPlace.geometry.location.lng()
					)
					// console.log(marker.getPosition(), this.currentPlace.geometry, dist);
				}
				result.push({
					marker,
					dist,
				})
			}
		})
		result.sort((a, b) => {
			return a.dist - b.dist
		})
		const resultContainer = document.querySelector('.result-search-bloc .content ul.gmaplist')
		let resultHTML = ''
		result.forEach(({ marker, dist }) => {
			if (marker.data.f == 'fr') {
				resultHTML += `
        <li id="${marker.data.i}" data-dist="${dist}">
          <address itemscope itemtype="http://schema.org/PostalAddress">`
				if (marker.data.n)
					resultHTML += `
            <h3 itemprop="name">
                ${marker.data.n}
            </h3>`
				if (marker.data.a)
					resultHTML += `
            <div itemprop="streetAddress">
                ${marker.data.a}<br />`
				resultHTML += `
                ${marker.data.a2 ? marker.data.a2 + '<br />' : ''}`
				resultHTML += `
            </div>`
				resultHTML += `
            <div>`
				if (marker.data.z)
					resultHTML += `
              <span itemprop="postalCode">
              ${marker.data.z}
              </span>`
				if (marker.data.c)
					resultHTML += `
              <span itemprop="addressLocality">
              ${marker.data.c},
              </span>`
				if (marker.data.co)
					resultHTML += `
              <span itemprop="addressCountry">
              ${marker.data.co}
              </span>`
				resultHTML += `
            </div>`
				if (marker.data.p)
					resultHTML += `
            <div itemprop="telephone" content="${marker.data.p}">
              ${marker.data.p}
            </div>`
				resultHTML += `
          </address>
          <span class="arrow_right"></span>
        </li>
      `
			} else {
				// Version US only
				resultHTML += `
        <li id="${marker.data.i}" data-dist="${dist}" class="format_us">
          <address itemscope itemtype="http://schema.org/PostalAddress">`
				resultHTML += `<h3 itemprop="name">
                ${marker.data.n}
            </h3>`
				resultHTML += `<div itemprop="streetAddress">
                ${marker.data.a}`
				resultHTML += `<br />
                ${marker.data.a2 ? marker.data.a2 + '<br />' : ''}`
				resultHTML += `
            </div>
            <div>`
				resultHTML += `
              <span itemprop="addressCountry">
              ${marker.data.cn ? marker.data.cn : ''}
              </span>`
				resultHTML += `
            </div>`
				resultHTML += `
          <div itemprop="telephone" content="${marker.data.p}">
              ${marker.data.p ? marker.data.p : ''}
            </div>`
				resultHTML += `
          </address>
          <span class="arrow_right"></span>
        </li>
      `
			}
		})
		resultContainer.innerHTML = resultHTML
		if (this.currentShopId && document.getElementById(this.currentShopId)) {
			document.getElementById(this.currentShopId).classList.add('highlight')
			document.getElementById('results-map-list').classList.add('list_highlight')
		}
		resultContainer.querySelectorAll('li').forEach((item) => {
			item.addEventListener('click', (event) => {
				event.preventDefault()
				// console.log('****');
				// console.log(item.id);
				this.currentShopId = item.id
				document.querySelectorAll('.result-search-bloc .content ul li').forEach((li) => {
					li.classList.remove('highlight')
					document.getElementById('results-map-list').classList.remove('list_highlight')
				})
				// console.log(this.markersShop);
				this.cluster.markers().forEach((ms) => {
					// console.log('-------- ' + ms.data.id);
					if (ms.data.id === item.id) {
						ms.setOpacity(1)
						item.classList.add('highlight')
						document.getElementById('results-map-list').classList.add('list_highlight')
						this._map.setCenter(ms.position)
						this._map.setZoom(15)
					} else {
						ms.setOpacity(0.6)
					}
				})
			})
		})
		if (this.psContentResultStore) {
			this.psContentResultStore.update()
		}
	}

	_initBlocWebstores() {
		const blocWS = this.el.querySelector('.webstore-bloc')

		if (blocWS) {
			const content = blocWS.querySelector('.content')
			this.psBlocWS = new PerfectScrollbar(content, {
				handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'],
				suppressScrollX: true,
			})
			this.WSmodal = this.el.querySelector('.webstores-modal')
			$('#country-select-ws').selectric({
				maxHeight: 200,
				onInit: () => {
					const modalContent = this.WSmodal.querySelector('.content')
					this.psModalWS = new PerfectScrollbar(modalContent, {
						handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'],
						suppressScrollX: true,
					})
				},
			})
			$('#country-select-ws').on('change', (country) => {
				// console.log('SELECTRIC', country)
				this.selectWSCountry($('#country-select-ws option:selected').val())
			})
			document.getElementById('see-all-webstore-button').addEventListener('click', this.openWSModal.bind(this))
			this.WSmodal.querySelector('.close-modal-button').addEventListener('click', this.closeWSModal.bind(this))
		}
	}

	openWSModal(event) {
		// console.log('OPEN WS Modal')
		if (event) {
			event.preventDefault()
		}
		_wsModalOpened = true
		this.WSmodal.classList.add('js-modal-open')

		document.body.classList.add('no-scroll')

		// console.log(this.WSmodal)
		// showUIExtra(false);
		if (window.lang) {
			const countries = document.querySelectorAll('select[name="country"] option')
			// console.log(countries);

			let lg_index = 0
			countries.forEach((country, index) => {
				if (country.value === window.lang) {
					lg_index = index
				}
			})
			$('#country-select-ws').prop('selectedIndex', 0).selectric('refresh')
			// console.log(
			//   'INIT SELECT COUNTRY',
			//   $('#country-select-ws option:selected').val()
			// )
			this.selectWSCountry($('#country-select-ws option:selected').val())
		}
	}

	closeWSModal(event) {
		if (event) {
			event.preventDefault()
		}

		document.body.classList.remove('no-scroll')
		_wsModalOpened = false
		this.WSmodal.classList.remove('js-modal-open')
		// showUIExtra(true);
	}

	selectWSCountry(country) {
		$('.stores-list').hide()
		$(`.stores-list-${country}`).show()
		if (this.psModalWS) {
			this.psModalWS.update()
		}
		$('#country-select-ws').selectric('refresh')
	}

	_playVideoHandler(event) {
		this.el.querySelector('.background-wrapper').classList.add('video-playing')
	}

	checkLatitude(map) {
		if (this.minZoomLevel) {
			if (map.getZoom() < this.minZoomLevel) {
				map.setZoom(parseInt(this.minZoomLevel))
			}
		}

		var bounds = map.getBounds()
		var sLat = map.getBounds().getSouthWest().lat()
		var nLat = map.getBounds().getNorthEast().lat()
		if (sLat < -85 || nLat > 85) {
			//the map has gone beyone the world's max or min latitude - gray areas are visible
			//return to a valid position
			if (this.lastValidCenter) {
				map.setCenter(this.lastValidCenter)
			}
		} else {
			this.lastValidCenter = map.getCenter()
		}
	}

	resize(event) {
		if (_mapActive || _wsModalOpened) {
			// showUIExtra(false);
		}
		if (this.psModalWS) {
			this.psModalWS.update()
		}
	}
}

function _getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
	function deg2rad(deg) {
		return deg * (Math.PI / 180)
	}

	const R = 6371 // Radius of the earth in km
	const dLat = deg2rad(lat2 - lat1) // deg2rad below
	const dLon = deg2rad(lon2 - lon1)
	const a =
		Math.sin(dLat / 2) * Math.sin(dLat / 2) +
		Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2)
	const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
	const d = R * c // Distance in km
	return d
}

function getMapActive() {
	return _mapActive
}

function getWSModalOpened() {
	return _wsModalOpened
}

function closeMap() {
	if (_sl) {
		_sl.closeMap()
	}
}

function closeModalWS() {
	if (_sl) {
		_sl.closeWSModal()
	}
}

window.addEventListener(
	'DOMContentLoaded',
	(event) => {
		const section = document.getElementById('section_gmap-store-locator')
		if (section) {
			_sl = new StoreLocator(section)
		}
	},
	false
)

// window.googleMapsOnLoad = () => {
//   const section = document.getElementById('section_gmap-store-locator')
//   if (section) {
//     _sl = new StoreLocator(section, google.maps)
//   }
// }

// const language = window.lang || 'fr'
// const script = document.createElement('script')
// script.src =
//   '//maps.googleapis.com/maps/api/js?key=AIzaSyCVkAVEqmwrmsxhwU4yrkeMicwLYI_9iFs&language=' +
//   language +
//   '&v=3.50.8&callback=googleMapsOnLoad&libraries=places'
// script.async = true
// document.head.appendChild(script)
