<template>
  <button
    :class="[
      { 'is-multiple': TfProductSelector.allowMultiple },
      { 'is-active': isActive },
      { 'is-disabled': isDisabled },
      { 'is-parent-level': isParentLevel },
      'btn-product-option'
    ]"
    :data-test="`select ${product.label}`"
    :style="inlineStyle"
    @mouseover="hover = true"
    @mouseout="hover = false"
    @click="onClick"
  >
    {{ product.label }}
    <slot
      name="productOptionAppend"
      :product="product"
    />
  </button>
</template>

<script>
/**
 * The "Product Options" for the Project Product Product selector.
 *
 * @vuedoc
 * @exports ProductSelector/ProductOption
 * @category Components
 */
  export default {
    name: 'TfProductOption',
    inject: [
      'TfProductSelector',
      'productType',
    ],
    props: {
      isParentLevel: {
        type: Boolean,
        default: true,
      },
      product: {
        type: Object,
        required: true,
        default: () => ({}),
      },
    },
    data: () => ({
      hover: false,
    }),
    computed: {
      /**
       * Determines if the product options is selected.
       *
       * @returns {boolean}
       */
      isActive() {
        return this.TfProductSelector.value.includes(this.product.id);
      },
      /**
       * If productSelector is themed, set corresponding CSS colors
       *
       * @returns {object }
       */
      inlineStyle() {
        const style = {};

        if (this.TfProductSelector.themePrimaryColor) {
          if (this.isActive) {
            style.backgroundColor = this.TfProductSelector.themePrimaryColor;
          }
        }

        if (this.TfProductSelector.themeHoverColor && !this.isActive && this.hover) {
          style.backgroundColor = this.TfProductSelector.themeHoverColor;
          style.color = this.TfProductSelector.themePrimaryColor;
        }

        return style;
      },
      /**
       * Determines if the product options is disabled.
       *
       * @returns {boolean}
       */
      isDisabled() {
        return this.TfProductSelector.disabledProducts.includes(this.product.id);
      },
    },
    methods: {
      /**
       * Emits the appropriate inject/emit types and payload.
       *
       * @param {string} type
       * @param {string} emit
       * @param {object} payload
       */
      emitPayload(type, emit, payload) {
        this[type].$emit(emit, payload);
      },
      /**
       * Adds or removed the product ID and emits from the root TfProductSelector component.
       *
       */
      onClick() {
        if (this.isDisabled) {
          return;
        }

        if (!this.TfProductSelector.allowMultiple && this.isActive) {
          this.emitPayload('productType', 'hidePopover');
          return;
        }

        const oldValue = [...this.TfProductSelector.value];
        const productId = this.product.id;
        let action;
        let selectedProductIds = this.TfProductSelector.allowMultiple
          ? this.TfProductSelector.value
          : [];

        if (selectedProductIds.includes(productId)) {
          this.$delete(
            selectedProductIds,
            selectedProductIds.findIndex((id) => id === productId),
          );
          action = 'deleted';
        } else {
          action = this.TfProductSelector.allowMultiple ? 'added' : 'changed';
          selectedProductIds.push(productId);
        }

        selectedProductIds = this.$TF.Formatting
          .sortObjects(
            selectedProductIds.map(
              (id) => this.TfProductSelector.products.find((product) => product.id === id),
            ),
            'position',
          )
          .map((product) => product.id);

        // Emits for all the changes
        this.emitPayload(
          'TfProductSelector',
          'input',
          selectedProductIds,
        );
        this.emitPayload(
          'TfProductSelector',
          'change',
          {
            oldValue,
            value: selectedProductIds,
          },
        );
        this.emitPayload(
          'TfProductSelector',
          'selectProductOption',
          {
            action,
            productId,
            selectedProductIds,
          },
        );

        if (!this.TfProductSelector.allowMultiple) {
          this.emitPayload('productType', 'hidePopover');
        }
      },
    },
  };
</script>

<style lang="scss" scoped>
  @import 'src/assets/styles/variables';

  .btn-product-option {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: 10px 15px 10px 30px;
    font-size: 14px;
    border: none;
    border-bottom: 1px solid $tf-extra-light-gray-1;
    background: $tf-extra-light-gray-2;
    cursor: pointer;

    &.is-active {
      color: $tf-white;
      background: $tf-blue;

      &,
      &:not(.is-disabled) {
        cursor: default;
      }

      &.is-multiple {
        cursor: pointer;
      }
    }

    &.is-disabled {
      color: $tf-light-gray;
      cursor: not-allowed;
    }

    &:not(.is-parent-level) {
      padding-left: 30px;
    }
  }
</style>
