<template>
  <div :class="$style.dropdownContent">
    <div
      :class="[$style.inputSearch, disabled ? $style.disabledStyle : '']"
      @click="openLists"
    >
      <input
        type="text"
        v-bind:readonly="isReadOnly"
        autocomplete="off"
        :class="[
          { errorNotice: noticeError },
          disabled ? $style.disabledStyle : ''
        ]"
        :placeholder="placeholderHeading"
        v-model="selectedName"
      />
      <div
        :class="[
          $style.iconRotate,
          disabled ? $style.disabledStyle : '',
          { errorNotice: noticeError }
        ]"
      >
        <i
          class="icon-arrow-up22"
          style="padding-top: 1px;padding-right: 7px"
          v-if="showListsSearch"
        ></i>
        <i
          v-else
          class="icon-arrow-down22"
          style="padding-top: 1px; padding-right: 7px"
        ></i>
      </div>
    </div>
    <transition name="fadeHeight">
      <div :class="$style.optionsLists" v-if="showListsSearch" @click.stop>
        <ul>
          <div v-if="searchVisible" :class="$style.inputFilter">
            <div :class="$style.iconSearch">
              <i class="icon-search4"></i>
            </div>
            <input
              ref="input"
              type="text"
              autocomplete="off"
              :placeholder="placeholderSearch"
              v-model="searchQuery"
              :class="$style.input"
            />
          </div>
          <li
            style="height: 36px"
            v-if="resultQuery.length > 0 && showAll"
            @click.capture.stop="checkAll()"
          >
            <input
              type="checkbox"
              id="todos"
              value="todos"
              name="todos"
              v-model="isCheckAll"
              :style="getOptionStyle(isCheckAll)"
            />
            <label style="padding-left: 13px">Todos</label>
          </li>
          <li
            v-for="(element, index) in (options, resultQuery)"
            :key="index"
            style="height: 36px"
          >
            <input
              type="checkbox"
              :id="element[filterBy]"
              :value="element"
              :name="element[filterBy]"
              v-model="selected"
              @change="dispatchListsSelected"
              :style="getOptionItem(element, selected)"
            />&nbsp;
            <label
              style="padding-left: 13px"
              :for="element[filterBy]"
              v-html="element[filterBy]"
            ></label>
          </li>
          <div :class="$style.disclaimer" v-if="resultQuery.length <= 0">
            <small v-html="noItems"></small>
          </div>
        </ul>
        <div
          @click="showListsSearch = !true"
          v-if="resultQuery.length > 0"
          :class="$style.returnTop"
          :style="{
            'background-color': selectedColor,
            'border-color': selectedColor
          }"
        >
          <i class="icon-arrow-up12"></i>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  name: "DropdownMultiSelect",
  props: {
    // Necesario para v-model
    value: {
      type: [Number, String, Array],
      default: null
    },
    selectedColor: {
      type: String,
      default: "#ba2c2c"
    },
    delimiter: {
      type: String,
      default: ", "
    },
    // Las opciones del multiselect
    options: {
      type: Array,
      required: true
    },
    // Permite filtar por propiedad del objeto para mostrar en el componente una vez seleccionado
    filterBy: {
      type: String,
      default: "name"
    },
    // Mostar búsqueda.
    searchVisible: {
      type: Boolean,
      default: true
    },
    // Placeholder del componente
    placeholderHeading: {
      type: String,
      default: "Seleccionar..."
    },
    // Placeholder del input de búsqueda
    placeholderSearch: {
      type: String,
      default: "Buscar..."
    },
    // Placeholder cuando no existan resultados de búsqueda.
    noItems: {
      type: String,
      default: "Sin resultados"
    },
    // Si es true, al iniciar el componente va a seleccionar todos los elementos.
    allSelect: {
      type: Boolean,
      default: true
    },
    // Si es true, muestra la "opción" de seleccionar todos.
    showAll: {
      type: Boolean,
      default: true
    },
    // Si es true, se muestra con apariencia de error (validación)
    noticeError: {
      type: Boolean,
      default: false
    },
    // Si es true, está deshabilitado.
    disabled: {
      type: Boolean,
      default: false
    },
    // Permite cambiar el texto de lo seleccionado, cuando el número de opciones seleccionadas sea mayor a este número.
    // Se deshabilita con 0.
    trim: {
      type: Number,
      default: 0
    },
    // El texto cuando se hace trim (Ej: 3 opciones seleccionadas)
    trimText: {
      type: String,
      default: "opciones seleccionadas"
    }
  },
  data() {
    return {
      isReadOnly: true,
      selected: [],
      selectedName: "",
      isCheckAll: false,
      searchQuery: "",
      showListsSearch: false
    };
  },
  watch: {
    value(antes, ahora) {
      // console.log(antes, ahora);
      //console.log("Watch value: ",JSON.stringify(val));
      if (antes == ahora) {
        this.selected = ahora;
      }
      this.selected = antes;
      this.dispatchListsSelected();
    }
  },
  mounted() {
    if (this.allSelect == true) {
      const self = this;
      setTimeout(function() {
        self.checkAll();
        self.dispatchListsSelected();
      }, 1000);
    }

    if (this.value != null) {
      this.selected = this.value;
      this.dispatchListsSelected();
      this.hideToogle();
    }
  },
  methods: {
    getOptionStyle(val) {
      //console.log(val)
      if (val) {
        return {
          "background-color": this.selectedColor,
          "border-color": this.selectedColor
        };
      } else {
        return {};
      }
    },
    getOptionItem(obj, selected) {
      //console.log(obj, selected)
      if (selected.findIndex(el => el === obj) !== -1) {
        return {
          "background-color": this.selectedColor,
          "border-color": this.selectedColor
        };
      } else {
        return {};
      }
    },
    openLists() {
      //console.log("openLists", this.disabled);
      if (!this.disabled) {
        this.showListsSearch = !this.showListsSearch;
        if (this.showListsSearch === true) {
          if (this.searchVisible !== false) {
            setTimeout(() => {
              this.$refs.input.focus();
            }, 100);
          }
        }
        setTimeout(
          () => document.addEventListener("click", this.hideToogle),
          0
        );
      }
    },
    dispatchListsSelected() {
      this.selectedName = "";
      const listSlugAero = [];

      //console.log("Before ",JSON.stringify(this.selected), JSON.stringify(this.isCheckAll));

      this.selected.forEach(item => {
        listSlugAero.push(item.label);
      });

      if (
        this.selected.length === 0 ||
        this.selected.length < this.options.length
      ) {
        this.isCheckAll = false;
      }
      // 07/12/2020: @Andres: Se modifica para agregar una coma y espacio como separador.
      let selectedNameArray = [];
      this.selected.forEach(element => {
        selectedNameArray.push(element[this.filterBy]);
      });
      if (selectedNameArray.length > 0) {
        //console.log(this.options.length, selectedNameArray.length);
        if (this.options.length == selectedNameArray.length) {
          this.selectedName = "Todos";
          this.isCheckAll = true;
        } else if (this.trim > 0 && selectedNameArray.length >= this.trim) {
          this.selectedName = selectedNameArray.length + " " + this.trimText;
        } else {
          this.selectedName = selectedNameArray.join(this.delimiter);
        }
      } else {
        this.selectedName = "";
      }
      //console.log("After ",JSON.stringify(this.selected), JSON.stringify(this.isCheckAll));
      this.$emit("input", this.selected);
    },
    checkAll() {
      //console.log("checkAll")
      this.isCheckAll = !this.isCheckAll;
      this.selected = [];
      this.selectedName = "";
      if (this.isCheckAll) {
        for (let key in this.options) {
          this.selected.push(this.options[key]);
        }
        this.selectedName = "Todos";
      }
      this.$emit("input", this.selected);
    },
    hideToogle() {
      if (this.selected.length > 0) {
        this.$emit("hide", this.selected);
      }
      this.showListsSearch = false;
      setTimeout(() => document.removeEventListener("click", this.hideToogle));
    }
  },
  computed: {
    resultQuery() {
      if (this.searchQuery) {
        return this.options.filter(elm => {
          return this.searchQuery
            .toLowerCase()
            .split(" ")
            .every(v => elm[this.filterBy].toLowerCase().includes(v));
        });
      } else {
        return this.options;
      }
    }
  }
};
</script>

<style lang="css">
.errorNotice {
  border: solid 1px #f79483 !important;
}
</style>

<style lang="scss" module>
.disabledStyle {
  /*opacity: 0.7;*/
  color: #b0b0b0 !important;
  cursor: not-allowed !important;
}
.dropdownContent {
  height: 36px;
  position: relative;

  .inputSearch {
    position: relative;
    width: 100%;
    input {
      outline: none;
      width: 100%;
      /*font-size: 13px;*/
      border-radius: 3px;
      border: solid 1px #dddddd;
      //box-shadow: 0 0 0 100px rgba(0, 0, 0, 0.03) inset;
      color: #333333;
      height: 36px;
      padding: 7px 29px 7px 12px;
      &:hover {
        cursor: pointer;
      }
    }
    .iconRotate {
      height: 100%;
      width: 29px;
      position: absolute;
      right: 0;
      top: 0;
      display: grid;
      align-content: center;
      /* position: absolute;
      right: 0;
      top: 0;
      padding: 9px 11px 5px 11px;
      background-color: transparent;
      border-top-right-radius: 3px;
      border-left: 1px solid #dddddd;*/
      &:hover {
        cursor: pointer;
      }
    }
  }

  .optionsLists {
    margin-top: 2px;
    min-width: 180px;
    padding-top: 7px;
    padding-bottom: 7px;
    background-color: #ffffff;
    border: solid 1px #dddddd;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 3px;
    border-top: none;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    z-index: 2;
    position: relative;

    .optionAll {
      padding-top: 8px;
      padding-bottom: 8px;
      padding-left: 12px;
      padding-right: 12px;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      flex-direction: row;
      label {
        margin-left: 10px;
        margin-bottom: 0;
        &:hover {
          cursor: pointer;
        }
      }
      @extend .classListsDropdopwn;
      @extend .classCheck;
    }
    ul {
      list-style: none;
      padding: 0;
      margin: 0;
      max-height: 320px;
      overflow: hidden;
      overflow-y: scroll;
      li {
        @extend .classListsDropdopwn;
        display: flex;
        align-items: center;
        margin-bottom: 1px;
        font-size: 13px;
        margin: 0px;
        /*padding-top: 8px;
        padding-bottom: 8px;*/
        padding-left: 12px;
        padding-right: 12px;
        label {
          padding-top: 8px;
          width: 100%;
          height: 100%;
          margin-bottom: 0;
          &:hover {
            cursor: pointer;
          }
        }
        @extend .classCheck;
      }

      .inputFilter {
        padding-top: 5px;
        padding-bottom: 5px;
        padding-left: 12px;
        padding-right: 12px;
        margin-bottom: 5px;
        //border-bottom: solid 1px #dddddd;
        position: relative;
        input {
          width: 100%;
          font-size: 13px;
          border: solid 1px #dddddd;
          outline: none;
          padding: 7px 12px 7px 36px;
          border-radius: 3px;
        }
        .iconSearch {
          position: absolute;
          left: 23px;
          top: 12px;
          opacity: 0.5;
          & i {
            font-size: 12px;
            //color: #cecece;
          }
        }
      }

      .disclaimer {
        padding: 10px;
        text-align: center;
        small {
          font-size: 12px;
        }
      }
    }
    .returnTop {
      background-color: #ff9800; // #336b87;
      position: absolute;
      right: 12px;
      bottom: 11px;
      padding: 2px 10px 4px 10px;
      border-radius: 3px;
      i {
        font-size: 16px;
        color: #ffffff;
      }
      &:hover {
        cursor: pointer;
      }
    }
  }
}

.classListsDropdopwn {
  // padding: 10px;
  //border-bottom: solid 1px #dddddd;
  transition: all ease 0.3s;
  font-size: 13px;
  &:hover {
    background-color: #f2f2f2;
    cursor: pointer;
  }
}

.classCheck {
  input[type="checkbox"] {
    position: relative;
    min-width: 20px;
    width: 20px;
    height: 20px;
    color: #000;
    border: 1px solid #dddddd;
    border-radius: 3px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    outline: 0;
    cursor: pointer;
    margin: 0;
    transition: background 175ms cubic-bezier(0.1, 0.1, 0.25, 1);
    &:checked {
      color: #fff;
      border-color: #ff9800;
      background: #ff9800;
      outline: none;

      &:before {
        opacity: 1;
      }
    }

    &:before {
      outline: none;
      position: absolute;
      content: "";
      display: block;
      top: 4px;
      left: 6px;
      width: 5px;
      height: 9px;
      border-style: solid;
      border-color: #fff;
      border-width: 0 2px 2px 0;
      transform: rotate(45deg);
      opacity: 0;
    }
  }
}
</style>

<style lang="css">
.fadeHeight-enter-active,
.fadeHeight-leave-active {
  transition: all 0.2s;
}
.fadeHeight-enter,
.fadeHeight-leave-to {
  opacity: 0;
}
</style>
