<template>
  <div
    v-show="!isHidden"
    class="form-group"
    :class="[
      columnSize,
      {
        'has-icon': faIcon,
        'has-feedback': hasFeedback,
        'has-success': hasSuccess,
        'has-error': hasError,
      },
    ]"
  >
    <label class="control-label" :for="id">
      {{ label }}
      <span class="info">{{ info }}</span>
      <span v-if="isRequired" class="required-marker"></span>
      <span
        v-if="tooltip"
        class="tooltip-info"
        data-toggle="tooltip"
        :title="tooltip"
      ></span>
    </label>
    <div class="dropdown" :class="{ open: showDropDown }">
      <!-- Selected Item -->
      <input
        type="text"
        class="hidden"
        :id="id + 'Value'"
        :value="inputValue"
      />
      <button
        v-if="inputValue"
        type="button"
        class="form-control dropdown-toggle"
        :id="id + 'Button'"
        :disabled="!isEnabled"
        @click="setOnFocus()"
        v-html="selectedOption + '<span class=caret></span>'"
      ></button>
      <!-- Default -->
      <button
        v-else
        type="button"
        class="form-control dropdown-toggle"
        :id="id"
        :disabled="!isEnabled"
        @click="setOnFocus()"
      >
        {{ text }}
        <span class="caret"></span>
      </button>
      <!-- Drop Menu -->
      <div class="dropdown-menu">
        <div
          :class="dropdownMenuClassAndStyle['wrapperClass']"
          :style="dropdownMenuClassAndStyle['wrapperStyle']"
        >
          <div
            :class="dropdownMenuClassAndStyle['scrollClass']"
            :style="dropdownMenuClassAndStyle['scrollStyle']"
          >
            <ul v-if="options" class="dropdown-menu">
              <DropdownOption
                v-for="(v, k) in dropdownOptions"
                :key="k"
                :k="k"
                :v="v"
                :is_slot="false"
                @select="onSelect($event)"
              ></DropdownOption>
            </ul>
            <DropdownOptionSlot
              v-else
              @select="onSelect($event)"
              @mounted="onOptionRegistered($event)"
              @optionHeight="onOptionHeight($event)"
            >
              <slot></slot>
            </DropdownOptionSlot>
          </div>
        </div>
      </div>
      <span v-if="faIcon" class="form-control-feedback" :class="faIcon"></span>
      <div
        v-if="validationText && hasError"
        class="help-block"
        data-validation-error
      >
        {{ validationText }}
      </div>
      <p v-if="help && !validationText" :id="id + 'Help'" class="help-block">
        {{ help }}
      </p>
    </div>
  </div>
</template>

<script>
import DropdownOption from "./DropdownOption.vue";
import DropdownOptionSlot from "./DropdownOptionSlot.vue";
import { str2bool } from "../../util";
export default {
  name: "bc-dropdown",
  components: {
    DropdownOption,
    DropdownOptionSlot,
  },
  props: {
    id: {
      type: String,
      default: null,
    },
    label: {
      type: String,
      default: null,
    },
    value: {
      type: [String, Number],
      default: null,
    },
    options: {
      type: [Array, Object],
    },
    info: {
      type: String,
      default: null,
    },
    icon: {
      type: String,
      default: null,
    },
    tooltip: {
      type: String,
      default: null,
    },
    help: {
      type: String,
      default: null,
    },
    validation: {
      type: String,
      default: null,
    },
    column_size: {
      type: Number,
      default: null,
    },
    is_enabled: {
      type: [Boolean, String],
      default: true,
    },
    is_hidden: {
      type: [Boolean, String],
      default: false,
    },
    is_required: {
      type: [Boolean, String],
      default: false,
    },
    is_valid: {
      type: [Boolean, String],
      default: null,
    },
    in_modal: {
      type: [Boolean, String],
      default: false,
    },
    text: {
      type: String,
      default: "Please select",
    },
  },
  data() {
    return {
      isOnFocus: false,
      isValid: null,
      inputValue: null,
      selectedOption: null,
      dropdownOptions: {},
      dropdownMenuMaxHeight: 312,
      dropdownItemHeight: 0,
    };
  },
  mounted() {
    if (this.value) {
      this.updateValue(this.value);
    }
    this.isValid = str2bool(this.is_valid, null);
  },
  updated() {
    if (this.value) {
      this.updateValue(this.value);
    }
    this.isValid = str2bool(this.is_valid, null);
  },
  watch: {
    options: {
      immediate: true,
      handler(newOptions) {
        console.log("options changed", this.id);
        if (newOptions) {
          if (Array.isArray(newOptions)) {
            this.dropdownOptions = newOptions.reduce(
              (a, v) => ({ ...a, [v]: v }),
              {}
            );
          } else {
            this.dropdownOptions = newOptions;
          }
        }
        this.$nextTick(() => {
          this.selectedOption = null;
          this.inputValue = null;
        });
      },
    },
    value: {
      immediate: true,
      handler(newValue) {
        // consol.log("Dropdown: value watch", newValue);
        this.updateValue(newValue);
      },
    },
  },
  created() {
    window.addEventListener("click", this.checkFocus);
  },
  destroyed() {
    window.removeEventListener("click", this.checkFocus);
  },
  computed: {
    isRequired() {
      return str2bool(this.is_required);
    },
    isHidden() {
      return str2bool(this.is_hidden, false);
    },
    isEnabled() {
      return str2bool(this.is_enabled, true);
    },
    inModal() {
      return str2bool(this.in_modal, false);
    },
    hasFeedback() {
      if (this.isValid == null) {
        return false;
      } else {
        return !this.isOnFocus;
      }
    },
    hasError() {
      return !this.isOnFocus && this.isValid === false && this.hasFeedback;
    },
    hasSuccess() {
      return !this.isOnFocus && this.isValid === true && this.hasFeedback;
    },
    columnSize() {
      if (this.column_size) {
        return `col-xs-${this.column_size}`;
      }
      return "";
    },
    faIcon() {
      if (this.icon) {
        return `fa-${this.icon}`;
      }
      return false;
    },
    validationText() {
      if (this.validation) {
        if (!this.isOnFocus) {
          return this.validation;
        }
      }
      return false;
    },
    showDropDown() {
      if (this.dropdownOptions && this.isOnFocus) {
        return true;
      }
      return false;
    },
    dropdownNbOptions() {
      if (this.dropdownOptions) {
        let optionsKeys = Object.keys(this.dropdownOptions);
        if (optionsKeys && Array.isArray(optionsKeys)) {
          return optionsKeys.length;
        }
      }
      return 0;
    },
    dropdownMenuClassAndStyle() {
      let classAndStyle = {
        wrapperClass: "scrollbars",
        wrapperStyle: "",
        scrollClass: "",
        scrollStyle: "",
      };
      if (this.inModal) {
        // render scrollable menu
        classAndStyle = {
          wrapperClass: "scroll-wrapper scrollbars scrollbar-inner",
          wrapperStyle: {
            position: "relative",
          },
          scrollClass:
            "scrollbars scrollbar-inner scroll-content scroll-scrolly_visible",
          scrollStyle: {
            height: "auto",
            "magin-bottom": "-12px",
            "magin-right": "-12px",
            "max-height": `${this.dropdownMenuMaxHeight}px`,
          },
        };
      }
      return classAndStyle;
    },
  },
  methods: {
    updateValue(value) {
      // console.log("Dropdown update value", value);
      this.inputValue = value;
      if (value) {
        this.$nextTick(() => {
          if (this.dropdownOptions && this.inputValue in this.dropdownOptions) {
            this.selectedOption = this.dropdownOptions[this.inputValue];
          }
        });
      } else {
        // value is empty or null, clear selected option
        this.selectedOption = null;
      }
    },
    onSelect({ key, value }) {
      this.inputValue = key;
      this.selectedOption = value;
      this.isOnFocus = false;
      this.$emit("input", key);
      this.$emit("select", key);
    },
    setOnFocus() {
      this.isOnFocus = !this.isOnFocus;
    },
    checkFocus(event) {
      // set onFocus = false if we quit the element
      if (!this.$el.contains(event.target)) {
        this.isOnFocus = false;
      }
    },
    onOptionRegistered({ key, value }) {
      this.dropdownOptions[key] = value;
    },
    onOptionHeight(value) {
      console.log("got height value", value);
    },
  },
};
</script>

