/**
 *
 */

export default class msMap {
	/**
	 * конструктор
	 * @param {*} options параметры
	 */
	constructor(
		options = {
			mapId: "5cc82180e6b9d406cb074a77",
			templateFolder: "acapella-2019"
		}
	) {
		this.mapId = options.mapId; //id карты с moscowseasons
		this.templateFolder = options.templateFolder; //папка шаблона для пина
		this.showPointInfo = true; //открываем ли пин по клику

		this.clusterer = null;
		this.objectManager = null;
		this.map = null;

		this.dataPoints = {
			items: []
		};

		this.coords = [];

		this.setBasePath();

		(async () => {
			await this.loadData();
			await this.initMap();
		})();
	}

	/**
	 * задаем пути к пинам
	 */
	setBasePath() {
		this.basePathPin = "/templates/" + this.templateFolder + "/assets/img/ms-map/icon-pin.svg";
		this.basePathPinActive = "/templates/" + this.templateFolder + "/assets/img/ms-map/icon-pin-active.svg";

		if (location.hostname == "localhost") {
			this.basePathPin = "/assets/img/ms-map/icon-pin.svg";
			this.basePathPinActive = "/assets/img/ms-map/icon-pin-active.svg";
		}

		if (location.hostname == "new-year.bnweb.studio") {
			this.basePathPin = "/acapella-2019/assets/img/ms-map/icon-pin.svg";
			this.basePathPinActive = "/acapella-2019/assets/img/ms-map/icon-pin-active.svg";
		}

		if (location.hostname == "www.mos.ru" || location.host == "newmos.mos.ru") {
			this.basePathPin = "https://moscowseasons.com/templates/" + this.templateFolder + "/assets/img/ms-map/icon-pin.svg";
			this.basePathPinActive = "https://moscowseasons.com/templates/" + this.templateFolder + "/assets/img/ms-map/icon-pin-active.svg";
		}
	}

	/**
	 * загружаем данные
	 */
	async loadData() {
		fetch("https://moscowseasons.com/graphql", {
			method: "POST",
			body: {
				data: `{
					"operationName":"map",
					"variables":{
						"id":"${this.mapId}"
					},
					"query":"query map ($id: ID) {
						map(id: $id) {
							slug
							layers {
								header
								points {
									address {
										lat
										lon
										address
										__typename
									}
									title
									shortDesc
									event {
										slug
									}
									__typename
								}
								__typename
							}
							__typename
						}
						__typename
					}"
				}`
			}
		})
			.then(response => response.json())
			.then(data => {
				console.log("Fetch map data: ", data);
				let id = 1;

				data.data.map.layers.forEach(function(layer) {
					let points = [];
					let id2 = 1;

					layer.points.forEach(function(point) {
						if (!point) return;

						points.push({
							id: id2,
							title: point.title ? point.title : "",
							group_id: id,
							lat: point.address.lon,
							lon: point.address.lat,
							address: point.address.address,
							shortDesc: point.shortDesc ? point.shortDesc : null,
							slug: point.event ? point.event.slug : null,
							image: point.image ? point.image.resized.url : null
						});

						this.coords.push(point.address.lat + "_" + point.address.lon);

						id2++;
					});

					this.dataPoints.items.push({
						id: id,
						title: layer.header,
						entity_type: "groups",
						points: points
					});

					id++;
				});

				// data_points.items.push(data_points.items[0]);
				// data_points.items = data_points.items.slice(1, 5);

				this.dataPoints.items.forEach(function(layer) {
					let liNode = document.createElement("li");
					liNode.innerText = layer.title;
					document.querySelector(".ms-map__places").appendChild(liNode);
				});
			});
	}

	/**
	 * готовим яндекс карту
	 */
	async initMap() {
		/* global ymaps */
		ymaps.ready(function() {
			this.map = new ymaps.Map("ms-map__container", {
				center: [55.757, 37.62233],
				zoom: 11
			});

			this.map.margin.addArea({
				left: 0,
				top: 0
			});

			this.objectManager = new ymaps.ObjectManager({
				// Чтобы метки начали кластеризоваться, выставляем опцию.
				clusterize: true,
				// ObjectManager принимает те же опции, что и кластеризатор.
				gridSize: 64,
				// Макет метки кластера pieChart.
				clusterIconLayout: "default#pieChart"
			});

			this.clusterer = new ymaps.Clusterer({
				preset: "islands#invertedRedClusterIcons",
				groupByCoordinates: false,
				zoomMargin: 30,
				clusterDisableClickZoom: false
			});

			let clusterObjects = [];

			let coordsTemp = this.coords.slice();

			this.dataPoints.items.forEach(function(layer) {
				// Группы точек
				this.clusterObjects[layer.title] = [];

				layer.points.forEach(function(point) {
					//console.log(point);

					let lon = Number(point.lon);
					let lat = Number(point.lat);

					coordsTemp = coordsTemp.filter(item => item === point.lon + "_" + point.lat);

					let repeat = coordsTemp.length;

					//console.log(repeat);

					if (!repeat) return;

					let marker = new ymaps.Placemark(
						[lat, lon],
						{
							hintContent: point.address,
							//openEmptyBalloon: false,
							slug: point.slug,
							title: point.title,
							image: point.image,
							address: point.address,
							desc: point.shortDesc
						},
						{
							iconLayout: "default#image",
							iconImageHref: this.basePathPin,
							iconImageSize: [30, 30],
							iconImageOffset: [-15, -15],
							id: point.id,
							balloonPanelMaxMapArea: 0,
							openEmptyBalloon: false
						}
					);

					marker.events.add("click", () => {
						for (var keyLayer in clusterObjects) {
							clusterObjects[keyLayer].forEach(function(point) {
								point.options.set({
									iconImageHref: this.basePathPin,
									iconImageSize: [30, 30],
									iconImageOffset: [-15, -15]
								});
							});
						}

						marker.options.set({
							iconImageHref: this.basePathPinActive,
							iconLayout: "default#image",
							iconImageSize: [37, 50],
							iconImageOffset: [-18, -25]
						});

						this.map.margin.addArea({
							right: 0,
							bottom: 0
						});

						if (!this.showPointInfo) return false;

						if (marker.properties.get("slug") == null) {
							document.querySelector(".ms-map__event-inner").innerHTML = "";

							const wrapElement = document.createElement("div");
							wrapElement.classList.add("ms-map__event-wrap");

							const addressElement = document.createElement("div");
							addressElement.classList.add("ms-map__event-address", "ms-map__event-address--empty");
							addressElement.innerHTML = marker.properties.get("address");

							const descriptionElement = document.createElement("div");
							descriptionElement.classList.add("ms-map__event-dscr");
							descriptionElement.innerHTML = marker.properties.get("title");

							wrapElement.appendChild(addressElement);
							wrapElement.appendChild(descriptionElement);

							document.querySelector(".ms-map__event-inner").appendChild(wrapElement);

							document.querySelector(".ms-map__close").style.display = "block";

							if (!$(".ms-map__event").is(":visible") && $(window).width() > 641) {
								$(".ms-map__event").show();
							} else if (!$(".ms-map__event").is(":visible") && $(window).width() < 640) {
								$.fancybox.open([
									{
										src: "#map-event",
										slideShow: false,
										closeBtn: false,
										scrolling: false,
										buttons: [],
										touch: {
											vertical: false
										},
										baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' + '<div class="fancybox-inner">' + '<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' + '<div class="fancybox-toolbar">{{buttons}}</div>' + '<div class="fancybox-navigation">{{arrows}}</div>' + '<div class="fancybox-stage"></div>' + '<div class="fancybox-caption"></div>' + "</div>" + "</div>"
									}
								]);
							}
						} else {
							if (!$(".ms-map__event").is(":visible") && $(window).width() > 641) {
								$(".ms-map__event").fadeIn();
							} else if (!$(".ms-map__event").is(":visible") && $(window).width() <= 641) {
								$.fancybox.open([
									{
										src: "#map-event",
										slideShow: false,
										closeBtn: false,
										scrolling: false,
										buttons: [],
										touch: {
											vertical: false
										},
										baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' + '<div class="fancybox-inner">' + '<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' + '<div class="fancybox-toolbar">{{buttons}}</div>' + '<div class="fancybox-navigation">{{arrows}}</div>' + '<div class="fancybox-stage"></div>' + '<div class="fancybox-caption"></div>' + "</div>" + "</div>"
									}
								]);
							}

							$.ajax({
								type: "POST",
								url: "https://moscowseasons.com/graphql",
								dataType: "json",
								contentType: "application/json",
								data: JSON.stringify({
									operationName: "event",
									variables: {
										slug: marker.properties.get("slug"),
										locale: "RU"
									},
									query: "query event($slug: String) {  event(slug: $slug) { \n ...EventFragment __typename \n}  \n} \n fragment EventFragment on Event { \n ...ShortEventFragment __typename \n } \n fragment ShortEventFragment on Event { \n id \n locale \n slug \n title description address {\n    address\n __typename\n  }\n \n images { \n id \n url \n resized(width: 500, height: 500) {\n url \n __typename \n } \n  __typename \n } \n __typename \n } \n"
								}),
								success: function(data) {
									$(".ms-map__event-inner").html("");
									var event = data.data.event;

									var link = "/" + event.locale.toLowerCase() + "/event/" + event.slug;
									var target = "_blank";
									if (window.location.host == "www.mos.ru" || window.location.host == "newmos.mos.ru") {
										target = "_blank";
										link = "https://moscowseasons.com/" + event.locale.toLowerCase() + "/event/" + event.slug;
									}

									var image_src = "";
									if (event.images.length != 0) {
										image_src = event.images[0].resized.url;
									}

									var wrap = $("<div/>", { class: "ms-map__event-wrap" });
									var img = $("<div/>", { class: "ms-map__event-img", style: "background-image: url(" + image_src + ")" });
									var title = $("<div/>", { class: "ms-map__event-title", text: event.title });
									var address = $("<div/>", { class: "ms-map__event-address", text: event.address.address });
									var description = $("<div/>", { class: "ms-map__event-dscr", html: marker.properties.get("desc") });
									var more = $("<a/>", { class: "ms-map__event-more", text: "Подробнее", href: link, target: target });

									wrap.append(description, address, more);
									$(".ms-map__event-inner").append(title, img, wrap);
									$(".ms-map__close").fadeIn();
								}
							});
						}
					});

					clusterObjects[layer.title].push(marker);
					clusterer.add(marker);
				});

				map.geoObjects.add(clusterer);
				objectManager.add(clusterObjects);
			});

			// удаляем лишние контролы
			map.controls.remove("searchControl");
			map.controls.remove("geolocationControl");
			map.controls.remove("typeSelector");
			map.controls.remove("trafficControl");

			var supportsTouch = "ontouchstart" in document.documentElement;
			if (supportsTouch) {
				map.behaviors.disable("drag");
			}

			map.controls.remove("fullscreenControl");

			if ($(document).width() >= 1200) {
				map.controls.remove("zoomControl");

				var zoomControl = new ymaps.control.ZoomControl({
					options: {
						position: {
							top: 108,
							right: 10,
							bottom: "auto",
							left: "auto"
						}
					}
				});

				map.controls.add(zoomControl);
			}

			// выключаем зум по скролу
			map.behaviors.disable(["scrollZoom"]);

			// автомасштаб
			map.setBounds(
				// map.geoObjects.getBounds(),
				clusterer.getBounds(),
				{
					checkZoomRange: true,
					zoomMargin: [20, 20, 20, 20]
				}
			).then(function() {
				//if( map.getZoom() > 15) map.setZoom(15);
			});
		});
	}
}

(function($, window, document, undefined) {
	var MSMap = (function() {
		var initMap = function() {
			$.ajax({
				type: "POST",
				url: "https://moscowseasons.com/graphql",
				data: '{"operationName":"map","variables":{"id":"' + map_id + '"},"query":"query map ($id: ID) {  map(id: $id) { slug layers{header points{address{lat lon address __typename}  title shortDesc event {slug } __typename} __typename}  __typename } __typename }"}',
				success: function(data) {
					//console.log(data_points.items);

					/* Yandex maps */
					ymaps.ready(function() {
						map = new ymaps.Map("ms-map__container", {
							center: [55.757, 37.62233],
							zoom: 11
						});

						map.margin.addArea({
							left: 0,
							top: 0
							// width: zoom_offset,
							// height: '100%'
						});

						objectManager = new ymaps.ObjectManager({
							// Чтобы метки начали кластеризоваться, выставляем опцию.
							clusterize: true,
							// ObjectManager принимает те же опции, что и кластеризатор.
							gridSize: 64,
							// Макет метки кластера pieChart.
							clusterIconLayout: "default#pieChart"
						});

						clusterer = new ymaps.Clusterer({
							preset: "islands#invertedRedClusterIcons",
							groupByCoordinates: false,
							//gridSize: 120,
							zoomMargin: 30,
							clusterDisableClickZoom: false
						});

						var clusterObjects = [];

						var coords_temp = coords.slice();

						data_points.items.forEach(function(layer) {
							// Группы точек
							clusterObjects[layer.title] = [];

							layer.points.forEach(function(point) {
								//console.log(point);

								var lon = Number(point.lon);
								var lat = Number(point.lat);

								//var repeat = coords_temp.filter(item => item === point.lon + '_' + point.lat).length;

								var repeat = coords_temp.filter(function(item) {
									if (item === point.lon + "_" + point.lat) {
										return item;
									}
								}).length;

								//console.log(repeat);

								if (repeat === 0) {
									return;
								} else if (repeat > 1) {
									$.each(coords_temp, function(index, coord) {
										if (coord == point.lon + "_" + point.lat) {
											coords_temp.splice(index, 1);
										}
									});
								}

								var marker = new ymaps.Placemark(
									[lat, lon],
									{
										hintContent: point.address,
										//openEmptyBalloon: false,
										slug: point.slug,
										title: point.title,
										image: point.image,
										address: point.address,
										desc: point.shortDesc
									},
									{
										iconLayout: "default#image",
										iconImageHref: base_path_pin,
										iconImageSize: [30, 30],
										iconImageOffset: [-15, -15],
										id: point.id,
										balloonPanelMaxMapArea: 0,
										openEmptyBalloon: false
									}
								);

								marker.events.add("click", function(e) {
									for (var keyLayer in clusterObjects) {
										clusterObjects[keyLayer].forEach(function(point) {
											point.options.set({
												iconImageHref: base_path_pin,
												iconImageSize: [30, 30],
												iconImageOffset: [-15, -15]
											});
										});
									}

									marker.options.set({
										iconImageHref: base_path_pin_active,
										iconLayout: "default#image",
										iconImageSize: [37, 50],
										iconImageOffset: [-18, -25]
									});

									map.margin.addArea({
										right: 0,
										bottom: 0
										//width: 500,
										//height: '100%'
									});

									if (!point_info) return false;

									if (marker.properties.get("slug") == null) {
										$(".ms-map__event-inner").html("");
										var wrap = $("<div/>", { class: "ms-map__event-wrap" });
										var address = $("<div/>", { class: "ms-map__event-address ms-map__event-address--empty", text: marker.properties.get("address") });
										var description = $("<div/>", { class: "ms-map__event-dscr", html: marker.properties.get("title") });

										wrap.append(address, description);
										$(".ms-map__event-inner").append(wrap);
										$(".ms-map__close").fadeIn();

										if (!$(".ms-map__event").is(":visible") && $(window).width() > 641) {
											$(".ms-map__event").show();
										} else if (!$(".ms-map__event").is(":visible") && $(window).width() < 640) {
											$.fancybox.open([
												{
													src: "#map-event",
													slideShow: false,
													closeBtn: false,
													scrolling: false,
													buttons: [],
													touch: {
														vertical: false
													},
													baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' + '<div class="fancybox-inner">' + '<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' + '<div class="fancybox-toolbar">{{buttons}}</div>' + '<div class="fancybox-navigation">{{arrows}}</div>' + '<div class="fancybox-stage"></div>' + '<div class="fancybox-caption"></div>' + "</div>" + "</div>"
												}
											]);
										}
									} else {
										if (!$(".ms-map__event").is(":visible") && $(window).width() > 641) {
											$(".ms-map__event").fadeIn();
										} else if (!$(".ms-map__event").is(":visible") && $(window).width() <= 641) {
											$.fancybox.open([
												{
													src: "#map-event",
													slideShow: false,
													closeBtn: false,
													scrolling: false,
													buttons: [],
													touch: {
														vertical: false
													},
													baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' + '<div class="fancybox-inner">' + '<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' + '<div class="fancybox-toolbar">{{buttons}}</div>' + '<div class="fancybox-navigation">{{arrows}}</div>' + '<div class="fancybox-stage"></div>' + '<div class="fancybox-caption"></div>' + "</div>" + "</div>"
												}
											]);
										}

										$.ajax({
											type: "POST",
											url: "https://moscowseasons.com/graphql",
											dataType: "json",
											contentType: "application/json",
											data: JSON.stringify({
												operationName: "event",
												variables: {
													slug: marker.properties.get("slug"),
													locale: "RU"
												},
												query: "query event($slug: String) {  event(slug: $slug) { \n ...EventFragment __typename \n}  \n} \n fragment EventFragment on Event { \n ...ShortEventFragment __typename \n } \n fragment ShortEventFragment on Event { \n id \n locale \n slug \n title description address {\n    address\n __typename\n  }\n \n images { \n id \n url \n resized(width: 500, height: 500) {\n url \n __typename \n } \n  __typename \n } \n __typename \n } \n"
											}),
											success: function(data) {
												$(".ms-map__event-inner").html("");
												var event = data.data.event;

												var link = "/" + event.locale.toLowerCase() + "/event/" + event.slug;
												var target = "_blank";
												if (window.location.host == "www.mos.ru" || window.location.host == "newmos.mos.ru") {
													target = "_blank";
													link = "https://moscowseasons.com/" + event.locale.toLowerCase() + "/event/" + event.slug;
												}

												var image_src = "";
												if (event.images.length != 0) {
													image_src = event.images[0].resized.url;
												}

												var wrap = $("<div/>", { class: "ms-map__event-wrap" });
												var img = $("<div/>", { class: "ms-map__event-img", style: "background-image: url(" + image_src + ")" });
												var title = $("<div/>", { class: "ms-map__event-title", text: event.title });
												var address = $("<div/>", { class: "ms-map__event-address", text: event.address.address });
												var description = $("<div/>", { class: "ms-map__event-dscr", html: marker.properties.get("desc") });
												var more = $("<a/>", { class: "ms-map__event-more", text: "Подробнее", href: link, target: target });

												wrap.append(description, address, more);
												$(".ms-map__event-inner").append(title, img, wrap);
												$(".ms-map__close").fadeIn();
											}
										});
									}
								});

								clusterObjects[layer.title].push(marker);
								clusterer.add(marker);
							});

							map.geoObjects.add(clusterer);
							objectManager.add(clusterObjects);
						});

						// удаляем лишние контролы
						map.controls.remove("searchControl");
						map.controls.remove("geolocationControl");
						map.controls.remove("typeSelector");
						map.controls.remove("trafficControl");

						var supportsTouch = "ontouchstart" in document.documentElement;
						if (supportsTouch) {
							map.behaviors.disable("drag");
						}

						map.controls.remove("fullscreenControl");

						if ($(document).width() >= 1200) {
							map.controls.remove("zoomControl");

							var zoomControl = new ymaps.control.ZoomControl({
								options: {
									position: {
										top: 108,
										right: 10,
										bottom: "auto",
										left: "auto"
									}
								}
							});

							map.controls.add(zoomControl);
						}

						// выключаем зум по скролу
						map.behaviors.disable(["scrollZoom"]);

						// автомасштаб
						map.setBounds(
							// map.geoObjects.getBounds(),
							clusterer.getBounds(),
							{
								checkZoomRange: true,
								zoomMargin: [20, 20, 20, 20]
							}
						).then(function() {
							//if( map.getZoom() > 15) map.setZoom(15);
						});
					});
				}
			});

			$(".ms-map__close").click(function() {
				$(this).fadeOut();
				if ($(window).width() < 640) {
					$.fancybox.close();
				} else {
					$(".ms-map__event").fadeOut();
				}
				$(".ms-map__event-inner").html("");
			});
		};

		return {
			/**
			 * инициализация модуля
			 */
			init: function() {
				var t = setInterval(function() {
					try {
						if (ymaps) {
							initMap();
							clearInterval(t);
						}
					} catch (err) {
						throw "ymaps not loaded yet";
					}
				}, 400);
			}
		};
	})();

	// Export
	window.MSMap = MSMap;
})(jQuery, this, this.document);
