<template>
  <div
    class="list-group list-button rounded-3 d-flex flex-column w-100 mb-2"
    :class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
    @keyup.space="triggerButton()"
    @keyup.up="handleKeyupArrow()"
    @keyup.down="handleKeyupArrow()"
    @keyup.left="handleKeyupArrow()"
    @keyup.right="handleKeyupArrow()"
  >
    <input
      :type="isMultiSelect ? 'checkbox' : 'radio'"
      :id="buttonID"
      :name="groupName"
      :value="value"
      :aria-required="isRequired"
      v-model="checkValue"
      @change="handleInputChange()"
    >
    <label
      tabindex="-1"
      :for="buttonID"
      :aria-labelledby="buttonID"
      class="d-flex flex-column justify-content-center py-3 px-4"
      @mouseup="triggerButton()"
    >
      <span
        class="m-0"
        :class="textPosition"
      >
        {{ buttonLabel }}
      </span>
      <span
        v-if="buttonLabelSubCopy"
        class="m-0 small"
        :class="textPosition"
      >
        {{ buttonLabelSubCopy }}
      </span>
      <span
        v-if="screenReaderOnlyText"
        class="sr-only"
      >
        {{ screenReaderOnlyText }}
      </span>
      <loader
        v-if="isLoaderDisplayed && selectingInitiatesLoad"
        :class="[this.loaderColor, this.loaderPosition]"
      />
    </label>
  </div>
</template>

<script>
import { useField } from "vee-validate";
import loader from "@/ux-components/loader/loader";
import { queryStrings } from "@/constants/query-strings";

export default {
  name: "listButton",
  props: {
    isMultiSelect: Boolean,
    groupName: String,
    buttonLabel: [Number, String],
    buttonID: [Number, String],
    isRequired: Boolean,
    textPosition: String,
    buttonLabelSubCopy: String,
    screenReaderOnlyText: String,
    selectingInitiatesLoad: Boolean,
    loaderColor: String,
    loaderPosition: String,
    value: {
    // Field initial value
      type: [String, Number],
      default: "",
    },
    validationRules: String,
    selectedValues: [Array, String],
    hasError: Boolean,
  },
  data() {
    return {
      isLoaderDisplayed: false,
      checkValue: Boolean,
    };
  },
  created() {
    if (Array.isArray(this.selectedValues)) {
      this.checkValue = this.isMultiSelect
        ? this.selectedValues.includes(this.value)
        : this.selectedValues[0];
    }
  },
  unmounted() { // needed to clear this button's selectedValues if it is removed
    this.checkValue = false;
    this.handleCheckChange();
  },
  methods: {
    displayLoader() {
      this.isLoaderDisplayed = true;
    },
    handleInputChange() {
        if(!this.selectingInitiatesLoad) {
          this.handleCheckChange();
        }
    },
    handleKeyupArrow() {
      if (this.isMultiSelect) {
        return; // Prevent arrow keys from doing anything if element is a checkbox
      }

      if(!this.selectingInitiatesLoad) {
        this.handleCheckChange();
      }
      this.handleChange(this.value);
    },
    triggerButton() {
      if(this.selectingInitiatesLoad) {
        this.displayLoader();
        this.handleCheckChange();
      }
      this.handleChange(this.value);
      this.pushEventToGA(this.$route.query[queryStrings.FMG_PAGE], this.GaActions.CLICKED, this.value.toString(), true);
    },
    handleCheckChange() {
      const emitEvent = {
        checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
        value: this.value.toString(),
        buttonId: this.buttonID && this.buttonID.toString(),
      };
      this.$emit("isCheckedChanged", emitEvent);
      this.$emit("update:modelValue", emitEvent);
    },
  },
  components: {
    loader,
  },
  setup(props) {
    const inputType = props.isMultiSelect ? "checkbox" : "radio";

    const fieldOptions = {
      type: inputType,
      checkedValue: props.value,
      potentialInitialValue: props.selectedValues,
    };

    // Set initialValue for validation setup if pre-selected
    // NOTE: props.selectedValues could be an array of strings, or an array of integers...
    if (props.selectedValues && (props.selectedValues.includes(props.value) || props.selectedValues.includes(parseInt(props.value)))) {
      fieldOptions['initialValue'] = fieldOptions.potentialInitialValue;
    }

    const {
      handleChange,
      errors,
    } = useField(props.groupName, props.validationRules, fieldOptions);

    return {
      handleChange,
      errors,
      fieldOptions, // only need to expose this for unit test purposes
    };
  },
};
</script>

<style lang="scss" scoped>
.list-group {
  &.list-button {
    outline: none;
    input[type="radio"],
    input[type="checkbox"] {
      position: static; //override bootstrap
      height: 0;
      opacity: 0;

      &:focus-visible + label {
        box-shadow: 0 0 0 2.5px $blue;
      }
      &:focus + label {
        box-shadow: 0 0 0 2.5px $blue;
      }
      &:checked + label {
        color: $black;
        font-weight: 500;
        background: $blue-100;
        box-shadow: 0 0 0 1px $blue;
      }
      &:checked:focus + label {
        box-shadow: 0 0 0 2.5px $blue;
      }
      &:checked + label p,
      &:checked + label span {
        font-weight: 500;
      }
      &:checked + label span:nth-child(2) {
        font-weight: 400;
        color: $gray-600;
      }
    }
  }
  label {
    color: $gray-600;
    position: relative;
    background: $white;
    transition: all 150ms linear;
    border-radius: $border-radius-lg;
    border: 1px solid $gray-500;
    width: 100%;
    outline: none;

    span {
      &.small {
        font-size: .75rem;
        color: $gray-550;
      }
    }

    &:hover {
      @include media-breakpoint-up(sm) {
        box-shadow: 0 0 0 4px $blue-300;
      }
      cursor: pointer;
    }
    + p {
      display: none;
    }
  }
}
</style>
