/* eslint-disable no-ternary, multiline-ternary */

import * as L from "leaflet";

export default class ControlsUI {
  constructor(awesomeMap) {
    this.awesomeMap = awesomeMap;

    this.main = L.control.layers(null, null, {
      position: "topleft",
      sortLayers: false,
      collapsed: this.awesomeMap.config.collapsedMenu
      // hideSingleBase: true
    });

    if (this.awesomeMap.config.hideControls) {
      $(this.main.getContainer()).hide();
    }

    this.$loading = $("#awesome-map .loading-spinner");
    this.onHashtag = this._orderHashtags;

    this.awesomeMap.map.on("overlayadd", () => {
      this.removeHiddenCategories();
    });
  }

  attach() {
    // legends
    this.main.addTo(this.awesomeMap.map);

    this.addSearchControls();
    if (this.awesomeMap.config.menu.categories) {
      this.addCategoriesControls();
    }

    // sub-layer hashtag title toggle
    $("#awesome-map").on("click", ".awesome_map-title-control", (evt) => {
      evt.preventDefault();
      evt.stopPropagation();
      $("#awesome_map-categories-control").toggleClass("active");
      $("#awesome_map-hashtags-control").toggleClass("active");
    });

    // hashtag events
    $("#awesome-map").on("change", ".awesome_map-hashtags-selector", (evt) => {
      evt.preventDefault();
      evt.stopPropagation();
      const tag = $(evt.target).closest("label").data("layer");
      // console.log("changed, layer", tag, "checked", evt.target.checked, e);
      if (tag) {
        this.updateHashtagLayers();
      }
    });

    // select/deselect all tags
    $("#awesome-map").on("click", ".awesome_map-toggle_all_tags", (evt) => {
      evt.preventDefault();
      evt.stopPropagation();
      $("#awesome-map .awesome_map-hashtags-selector").prop("checked", $("#awesome-map .awesome_map-hashtags-selector:checked").length < $("#awesome-map .awesome_map-hashtags-selector").length);
      this.updateHashtagLayers();
    });
  }

  addSearchControls() {
    $(this.main.getContainer()).contents("form").append(`<div id="awesome_map-categories-control" class="active"><b class="awesome_map-title-control">${window.DecidimAwesome.texts.categories}</b><div class="categories-container"></div></div>
    <div id="awesome_map-hashtags-control"><b class="awesome_map-title-control">${window.DecidimAwesome.texts.hashtags}</b><div class="hashtags-container"></div><a href="#" class="awesome_map-toggle_all_tags">${window.DecidimAwesome.texts.select_deselect_all}</a></div>`);
  }

  addCategoriesControls() {
    this.awesomeMap.categories.forEach((category) => {
      // add control layer for this category
      const label = `<i class="awesome_map-category_${category.id}"></i> ${category.name}`;
      this.awesomeMap.layers[category.id] = {
        label: label,
        group: new L.FeatureGroup.SubGroup(this.awesomeMap.cluster)
      };
      this.awesomeMap.layers[category.id].group.addTo(this.awesomeMap.map);
      $("#awesome_map-categories-control .categories-container").append(`<label data-layer="${category.id}" class="awesome_map-category-${category.id}${category.parent ? " subcategory" : ""}" data-parent="${category.parent}"><input type="checkbox" class="awesome_map-categories-selector" checked><span>${label}</span></label>`);
    })

    // category events
    $("#awesome-map").on("change", ".awesome_map-categories-selector", (evt) => {
      evt.preventDefault();
      evt.stopPropagation();

      const id = $(evt.target).closest("label").data("layer");
      const cat = this.awesomeMap.getCategory(id);
      // console.log("changed, layer", id, "cat", cat, "checked", evt.target.checked, e);
      if (cat) {
        const layer = this.awesomeMap.layers[cat.id];
        if (evt.target.checked) {
          // show group of markers
          this.awesomeMap.map.addLayer(layer.group);
        } else {
          // hide group of markers
          this.awesomeMap.map.removeLayer(layer.group);
          // cat.children().forEach((c) => {
          //   let $el = $(`.awesome_map-category-${c.id}`);
          //   if($el.contents("input").prop("checked")) {
          //     $el.click();
          //   }
          // });
        }
        // if it's a children, put the parent to indeterminate
        this._indeterminateParentInput(cat);
        // sync tags
        this.updateHashtagLayers();
      }
    });
  }

  // Hashtags are collected directly from proposals (this is different than categories)
  addHashtagsControls(hashtags, marker) {
    // show hashtag layer
    if (hashtags && hashtags.length) {
      $("#awesome_map-hashtags-control").show();
      hashtags.forEach((hashtag) => {
        // Add layer if not exists, otherwise just add the marker to the group
        if (!this.awesomeMap.layers[hashtag.tag]) {
          this.awesomeMap.layers[hashtag.tag] = {
            label: hashtag.name,
            group: new L.FeatureGroup.SubGroup(this.awesomeMap.cluster)
          };
          this.awesomeMap.map.addLayer(this.awesomeMap.layers[hashtag.tag].group);
          $("#awesome_map-hashtags-control .hashtags-container").append(`<label data-layer="${hashtag.tag}" class="awesome_map-hashtag-${hashtag.tag}"><input type="checkbox" class="awesome_map-hashtags-selector" checked><span>${hashtag.name}</span></label>`);
          // Call a trigger, might be in service for customizations
          this.onHashtag(hashtag, $("#awesome_map-hashtags-control .hashtags-container"));
        }
        this.awesomeMap.layers[hashtag.tag].group.addLayer(marker);

        const $label = $(`label.awesome_map-hashtag-${hashtag.tag}`);
        // update number of items
        $label.attr("title", `${parseInt($label.attr("title") || 0, 10) + 1} ${window.DecidimAwesome.texts.items}`);
      });
    }
  }

  showCategory(cat) {
    $("#awesome_map-categories-control").show();
    // show category if hidden
    const $label = $(`label.awesome_map-category-${cat.id}`);
    const $parent = $(`label.awesome_map-category-${cat.parent}`);
    $label.show();
    // update number of items
    $label.attr("title", `${parseInt($label.attr("title") || 0, 10) + 1} ${window.DecidimAwesome.texts.items}`);
    // show parent if apply
    $parent.show();
    $parent.attr("title", `${parseInt($parent.attr("title") || 0, 10) + 1} ${window.DecidimAwesome.texts.items}`);
  }

  removeHiddenComponents() {
    $(".awesome_map-component").each((_idx, el) => {
      const layer = this.awesomeMap.layers[$(el).data("layer")];
      const $input = $(el).closest("div").find("input:not(:checked)");
      if (layer && $input.length) {
        this.awesomeMap.map.addLayer(layer.group);
        this.awesomeMap.map.removeLayer(layer.group);
      }
    });
  }

  removeHiddenCategories() {
    $(".awesome_map-categories-selector:not(:checked)").each((_idx, el) => {
      const layer = this.awesomeMap.layers[$(el).closest("label").data("layer")];
      if (layer) {
        this.awesomeMap.map.addLayer(layer.group);
        this.awesomeMap.map.removeLayer(layer.group);
      }
    });
  }

  updateHashtagLayers() {
    // hide all
    $(".awesome_map-hashtags-selector").each((_idx, el) => {
      const layer = this.awesomeMap.layers[$(el).closest("label").data("layer")];
      if (layer) {
        this.awesomeMap.map.removeLayer(layer.group);
      }
    });
    // show selected only
    $(".awesome_map-hashtags-selector:checked").each((_idx, el) => {
      const layer = this.awesomeMap.layers[$(el).closest("label").data("layer")];
      if (layer) {
        this.awesomeMap.map.addLayer(layer.group);
      }
    });
    // hide non-selected categories
    this.removeHiddenComponents();
    this.removeHiddenCategories();
  }

  updateStats(uid, total) {
    // update component stats
    const $component = $(`#awesome_map-${uid}`);
    $component.attr("title", `${total} ${window.DecidimAwesome.texts.items}`);
  }

  _indeterminateParentInput(cat) {
    if (cat.parent) {
      let $input = $(`.awesome_map-category-${cat.parent}`).contents("input");
      let $subcats = $(`[class^="awesome_map-category-"][data-parent="${cat.parent}"]:visible`);
      let numChecked = $subcats.contents("input:checked").length;
      $input.prop("indeterminate", numChecked !== $subcats.length && numChecked !== 0);
    }
  }

  // order hashtags alphabetically
  _orderHashtags(_hashtag, $div) {
    let $last = $div.contents("label:last");
    if ($last.prev("label").length) {
      // move the label to order it alphabetically
      $div.contents("label").each((_idx, el) => {
        if ($(el).text().localeCompare($last.text()) > 0) {
          $(el).before($last);
        }
      });
    }
  }
}