<template>
  <label
    :class="[buttonWrapperClasses, { 'has-error': errors.length > 0 }]"
    :for="buttonId"
    @mousedown.left="handleEventAction('click', $event)"
  >
    <!-- classes: {{classes}}<br/>
    value: {{value}} <br/>
    modelValue: {{modelValue}} <br/>
    buttonId: {{buttonId}} <br/> -->
    <input
      :type="inputType"
      :id="buttonId"
      :name="groupName"
      :class="inputClasses"
      :aria-required="isRequired"
      :value="value"
      :checked="isChecked"
      @keypress.enter="handleEventAction('keypressSubmit', $event)"
      @keypress.space="handleEventAction('keypressSubmit', $event)"
      @change="handleEventAction('change', $event)"
    />

    <slot></slot>
  </label>
</template>

<script>
import { queryStrings } from "@/constants/query-strings";
import { useField } from "vee-validate";
import { toRef } from "vue";

export default {
  name: "input-button-wrapper",
  emits: ["change"],
  model: {
    prop: "modelValue",
    event: "change",
  },
  props: {
    value: {
      type: [String, Number],
      required: true,
    },
    modelValue: {
      type: [Array, String, Number],
      required: true,
    },
    isMultiSelect: Boolean,
    isWide: Boolean,
    buttonImage: String,
    buttonImageId: String,
    buttonLabel: {
      type: String,
      required: true,
    },
    isRequired: {
      type: Boolean,
      required: true,
    },
    buttonLabelSubCopy: {
      type: String,
      required: true,
    },
    groupName: {
      type: String,
      required: true,
    },
    validationRules: {
      type: String,
      default: "",
    },
    buttonWrapperClasses: [String, Array, Object],
    inputClasses: [String, Array, Object],
    valueToLogType: String,
    selectOnKeypress: Boolean,
  },
  data() {
    return {
      valueToEmit: null,
      hasFirstEventFired: false,
    };
  },
  methods: {
    handleEventAction(eventType, e) {
      const eventTypes = {
        CHANGE: "change",
        KEYPRESS_SUBMIT: "keypressSubmit",
        CLICK: "click",
      };

      if (!this.hasFirstEventFired) {
        switch (eventType) {
          case eventTypes.CLICK:
          case eventTypes.KEYPRESS_SUBMIT:
            console.log("clicking");
            this.handleClick(e);
            break;
          case eventTypes.CHANGE:
            console.log("selectOnKeypress: ", this.selectOnKeypress);
            this.selectOnKeypress
              ? this.handleClick(e)
              : this.handleSelectionChange(e);
            break;
        }
      }

      this.hasFirstEventFired = eventType !== eventTypes.CHANGE;

      console.log("handleKeypress: ", eventType);
      // console.log({
      //   selectOnKeypress: this.selectOnKeypress,
      //   event: e,
      //   eventType: eventType,
      //   isClick: eventType === "click",
      //   isKeypress: eventType === "keypress",
      // });
      // console.log(eventType)

      // click => click, keypress
      // space => keypressSubmit, keypress
      // arrow left/right => keypress

      // if selectOnKeypress (YMMS)
      // if click => emit event
      // if space/enter => emit event
      // if arrow => emit event
      // else (!selectOnKeypress)
      // if click => emit event
      // if space/enter => emit event
      // if arrow => handleSelection

      // if ((!this.selectOnKeypress && eventType === "click") || (this.selectOnKeypress && eventType === "keypress")) {
      // this.handleClick(e);
      // }
      // else {
      //   this.handleSelectionChange(e);
      // }
    },
    handleSelectionChange(e) {
      // console.log("HSC");
      // console.log(e);
      // console.log(this.value);
      // console.log(this.modelValue);
      // let isChecked = event.target.checked;
      // console.log("BM value: ", this.value);
      // let valueToEmit;
      // console.log("isMultiselect")
      // console.log(this.isMultiSelect)
      // console.log({
      //   modelValue: this.modelValue,
      //   isMultiselect: this.isMultiSelect
      // })
      if (
        this.isMultiSelect &&
        (this.modelValue instanceof Array || this.modelValue == null)
      ) {
        let newValue = this.modelValue ? [...this.modelValue] : [];
        // console.log("newValue", newValue)
        // console.log({
        //   newValue: newValue,
        //   // isChecked: isChecked
        // })
        if (!newValue.includes(this.value)) {
          // console.log("isChecked")
          newValue.push(this.value);
        } else {
          // console.log("isn't checked")
          newValue.splice(newValue.indexOf(this.value), 1);
        }

        this.valueToEmit = newValue;
      } else {
        this.valueToEmit = this.value;
      }

      // console.log("handlingChange", this.valueToEmit);
      this.handleChange(this.valueToEmit);
      this.pushClickEventToGA();
      // if (this.selectOnKeypress) {
      //   this.handleClick(e)
      // }
    },
    handleClick(e) {
      console.log("handleClick");
      this.handleSelectionChange(e);
      // console.log("HC");
      // console.log({
      //   eventEmitting: e,
      //   valueToEmit: this.valueToEmit,
      // });
      this.$emit("change", this.valueToEmit);
    },
    pushClickEventToGA() {
      this.pushEventToGA(
        this.$route.query[queryStrings.FMG_PAGE],
        this.GaActions.CLICKED,
        this.value.toString(),
        true,
        this.valueToLogType
      );
    },
  },
  computed: {
    isChecked() {
      if (this.isMultiSelect && this.modelValue instanceof Array) {
        this.modelValue.includes(this.value);
      }
      return this.modelValue === this.value;
    },
    inputType() {
      return this.isMultiSelect ? "checkbox" : "radio";
    },
    buttonId() {
      return `${this.groupName} ${JSON.stringify(this.value)}`;
    },
  },
  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, value } = useField(
    //   toRef(props, "groupName"),
    //   toRef(props, "validationRules"),
    //   fieldOptions
    // );

    console.log(props.validationRules);

    const { handleChange, errors, value } = useField(
      toRef(props, "groupName"),
      toRef(props, "validationRules"),
      fieldOptions
    );

    const validateValue = value;

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

<!-- TODO KO Scope this? -->
<style lang="scss">
input {
  opacity: 0;
  height: 0.1px; // NOTE: cannot be zero or Safari can't put focus on it
  width: 0;
}
</style>
