<template>
  <div class="demo-page">
    <div class="flex">
      <div id="container-product-selector">
        <TfProductSelector
          v-model="selectedIds"
          :allow-multiple="options.allowMultiple.value"
          :categories="options.breakIntoCategories.value ? categories : []"
          :disabled-products="disabledProducts"
          :input-border-color="inputBorderColor"
          :fixed-toggle="options.fixedToggle.value"
          :keep-open="options.keepOpen.value"
          :products="products"
          :show-category-titles="options.showCategoryTitles.value"
          :show-selected-count="options.showSelectedCount.value"
          :theme-primary-color="themePrimary"
          :theme-hover-color="themeHover"
          :width="400"
          @selectProductOption="onEmit('selectProductOption', $event)"
          @toggleCategory="onEmit('toggleCategory', $event)"
          @toggleProductType="onEmit('toggleProductType', $event)"
          @change="payloads.change = $event"
          @input="payloads.input = $event"
        >
          <!-- product option Icons -->
          <span
            v-if="options.slotType.value !== 'None'"
            slot="productOptionAppend"
            slot-scope="optionAppendProps"
            :class="[
              { active : selectedIds.includes(optionAppendProps.product.id) },
              'container-append-slot'
            ]"
          >
            <TfProgressIcon
              v-if="options.slotType.value === 'Validation'"
              :progress-state="optionValidationStates[optionAppendProps.product.id]"
              :is-active="selectedIds.includes(optionAppendProps.product.id)"
            />
            <template v-if="options.slotType.value === 'Checkbox'">
              <icon
                v-if="selectedIds.includes(optionAppendProps.product.id)"
                :style="{ fill : theme }"
                name="check-square"
              />
              <span
                v-else
                class="custom-empty square"
              />
            </template>
          </span>
        </TfProductSelector>
      </div>
      <div>
        <ElForm label-position="top">
          <h3>Customizations</h3>
          <ElFormItem
            v-for="formGroup in options"
            :key="formGroup.label"
            :label="`${formGroup.label} ${formGroup.prop ? '(prop)' : ''}`"
            size="medium"
          >
            <ElRadioGroup
              v-model="formGroup.value"
              size="small"
            >
              <ElRadioButton
                v-for="label in formGroup.options"
                :key="label"
                :label="label"
              />
            </ElRadioGroup>
          </ElFormItem>
        </ElForm>
      </div>
      <div>
        <ElForm label-position="top">
          <h3>Product Validation</h3>
          <ElFormItem
            v-for="(product, index) in products"
            :key="product.id"
            size="medium"
          >
            <p><strong>{{ product.label }}</strong></p>
            <ElRadioGroup
              v-model="product.validation"
              size="small"
              @change="validateProduct($event, index)"
            >
              <ElRadioButton label="None" />
              <ElRadioButton label="Half" />
              <ElRadioButton label="Full" />
            </ElRadioGroup>
            <p>
              <TfButton
                :type="product.declined ? 'primary' : 'decline'"
                size="text"
                @click="products[index].declined = !products[index].declined"
                v-text="product.declined ? 'Undo Decline' : 'Decline'"
              />
            </p>
          </ElFormItem>
        </ElForm>
      </div>
    </div>
    <div
      id="container-actions"
      class="flex"
    >
      <div>
        <h3>@props</h3>
        <p>
          <strong>allowMultiple:</strong>&nbsp;
          <code>{{ options.allowMultiple.value }}</code>
        </p>
        <p>
          <strong>themePrimaryColor:</strong>&nbsp;
          <code>{{ themePrimary }}</code>
        </p>
        <p>
          <strong>themeHoverColor:</strong>&nbsp;
          <code>{{ themeHover }}</code>
        </p>
        <p>
          <strong>disabledProducts:</strong>&nbsp;
          <code>{{ disabledProducts }}</code>
        </p>
        <p>
          <strong>inputBorderColor:</strong>&nbsp;
          <code>{{ inputBorderColor }}</code>
        </p>
        <p>
          <strong>fixedToggle:</strong>&nbsp;
          <code>{{ options.fixedToggle.value }}</code>
        </p>
        <p>
          <strong>keepOpen:</strong>&nbsp;
          <code>{{ options.keepOpen.value }}</code>
        </p>
        <p>
          <strong>showCategoryTitles:</strong>&nbsp;
          <code>{{ options.showCategoryTitles.value }}</code>
        </p>
        <p>
          <strong>showSelectedCount:</strong>&nbsp;
          <code>{{ options.showSelectedCount.value }}</code>
        </p>
      </div>
      <div>
        <h3>Emitted:</h3>
        <p>
          <strong>{{ payloads.emitted.name }}</strong><br>
          <pre>{{ payloads.emitted.payload }}</pre>
        </p>
      </div>
      <div>
        <h3>@Input:</h3>
        <p><pre>{{ payloads.input }}</pre></p>
      </div>
      <div>
        <h3>@Change:</h3>
        <p><pre>{{ payloads.change }}</pre></p>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'ProductSelectExample',
    data: () => ({
      allProducts: [
        // Stop loss category
        {
          alternative: false,
          declined: false,
          inforce_product: {
            valid_plan_design: true,
            valid_rate_structure: false,
          },
          label: 'Stop Loss',
          product_type_id: 1,
          product_type_name: 'Stop Loss',
        },
        {
          alternative: true,
          declined: false,
          inforce_product: {
            valid_plan_design: false,
            valid_rate_structure: false,
          },
          label: '125K',
          product_type_id: 1,
          product_type_name: 'Stop Loss',
        },
        {
          alternative: true,
          declined: false,
          inforce_product: {
            valid_plan_design: false,
            valid_rate_structure: false,
          },
          label: '250K',
          product_type_id: 1,
          product_type_name: 'Stop Loss',
        },
        // Dental/Vision
        {
          alternative: false,
          declined: false,
          inforce_product: {
            valid_plan_design: true,
            valid_rate_structure: true,
          },
          label: 'Dental',
          product_type_id: 2,
          product_type_name: 'Dental',
        },
        {
          alternative: true,
          declined: false,
          inforce_product: {
            valid_plan_design: false,
            valid_rate_structure: false,
          },
          label: 'Dental alt',
          product_type_id: 2,
          product_type_name: 'Dental',
        },
        {
          alternative: false,
          declined: true,
          inforce_product: {
            valid_plan_design: true,
            valid_rate_structure: false,
          },
          label: 'Vision w/ custom Label',
          product_type_id: 3,
          product_type_name: 'Vision',
        },
        // Life & Disability
        {
          alternative: false,
          declined: false,
          inforce_product: {
            valid_plan_design: true,
            valid_rate_structure: false,
          },
          label: 'Basic Life / AD&D',
          product_type_id: 4,
          product_type_name: 'Basic Life / AD&D',
        },
        {
          alternative: false,
          declined: false,
          inforce_product: {
            valid_plan_design: true,
            valid_rate_structure: false,
          },
          label: 'Volunary Life',
          product_type_id: 5,
          product_type_name: 'Volunary Life',
        },
        // Worksite
        {
          alternative: false,
          declined: false,
          inforce_product: {
            valid_plan_design: true,
            valid_rate_structure: true,
          },
          label: 'Critical Illness',
          product_type_id: 6,
          product_type_name: 'Critical Illness',
        },
      ],
      categories: [
        {
          label: 'Stop Loss',
          productTypeIds: [1],
        },
        {
          label: 'Life & Disability',
          productTypeIds: [4, 5],
        },
        // Putting this out of place as a test
        // `Dental/Vision`` usually goes above `Life/Disability`
        // Toggling `Break into categories` should rearrange the order.
        {
          label: 'Dental/Vision',
          productTypeIds: [2, 3],
        },
        {
          label: 'Worksite',
          productTypeIds: [6],
        },
      ],
      categoryActions: {
        action: null,
        clicked: null,
        expanded: [],
      },
      options: {
        keepOpen: {
          value: false,
          label: 'Keep open',
          prop: true,
          options: [false, true],
        },
        allowMultiple: {
          value: false,
          label: 'Allow multiple',
          prop: true,
          options: [false, true],
        },
        breakIntoCategories: {
          value: true,
          label: 'Break into categories',
          prop: false,
          options: [false, true],
        },
        showCategoryTitles: {
          value: true,
          label: 'Show category titles',
          prop: true,
          options: [false, true],
        },
        showSelectedCount: {
          value: false,
          label: 'Show Selected Count in the label',
          prop: true,
          options: [false, true],
        },
        fixedToggle: {
          value: true,
          label: 'Fix toggle to end',
          prop: true,
          options: [false, true],
        },
        disabledProductsFields: {
          value: 'Declined',
          label: 'Disable products',
          prop: true,
          options: ['None', 'Declined', 'Unfinished Base Products'],
        },
        slotType: {
          value: 'Validation',
          label: 'Slot Type',
          prop: false,
          options: [
            'None',
            'Validation',
            'Checkbox',
          ],
        },
        themePrimary: {
          value: 'None',
          label: 'Apply theme primary color',
          prop: true,
          options: ['None', '#1bc788', '#ff209c'],
        },
        themeHover: {
          value: 'None',
          label: 'Apply theme hover color',
          prop: true,
          options: ['None', '#feceff'],
        },
        inputBorderColor: {
          value: 'Default',
          label: 'Input border color',
          prop: true,
          options: ['Default', 'transparent', '#ff209c'],
        },
      },
      payloads: {
        emitted: {
          name: null,
          payload: null,
        },
        input: null,
        change: null,
      },
      products: [],
      productTypeActions: {
        action: null,
        clicked: null,
        expanded: [],
      },
      selectedIds: [],
    }),
    computed: {
      /**
       * The branded color for the input border
       *
       * @returns {string | null}
       */
      inputBorderColor() {
        return this.options.inputBorderColor.value === 'Default'
          ? null
          : this.options.inputBorderColor.value;
      },
      /**
       * Returns the 'branded' theme primary color
       *
       * @returns {string | null}
       */
      themePrimary() {
        return this.options.themePrimary.value === 'None'
          ? null
          : this.options.themePrimary.value;
      },
      /**
       * Returns the 'branded' theme hover color
       *
       * @returns {string | null}
       */
      themeHover() {
        return this.options.themeHover.value === 'None'
          ? null
          : this.options.themeHover.value;
      },
      /**
       * Creates an array disabled products to pass to `<TfProductSelector />`.
       *
       * @returns {Array}
       */
      disabledProducts() {
        let products = [];

        if (this.options.disabledProductsFields.value === 'Declined') {
          products = this.products
            .filter((product) => product.declined)
            .map((product) => product.id);
        } else if (this.options.disabledProductsFields.value === 'Unfinished Base Products') {
          this.products.forEach((product) => {
            if (product.alternative) {
              const baseProduct = this.products.find((baseProducts) => !baseProducts.alternative
                && baseProducts.product_type_id === product.product_type_id);

              if (baseProduct.state !== 'complete') {
                products.push(product.id);
              }
            }
          });
        }

        return products;
      },
      /**
       * Creates an object for all the validation states.
       *
       * @returns {object}
       */
      optionValidationStates() {
        const optionStates = {};

        this.products.forEach((product) => {
          let progressIcon = 'not-started';

          if (
            product.inforce_product.valid_plan_design
            || product.inforce_product.valid_rate_structure
          ) {
            progressIcon = product.inforce_product.valid_plan_design
              && product.inforce_product.valid_rate_structure
              ? 'full'
              : 'half';
          }

          optionStates[product.id] = progressIcon;
        });

        return optionStates;
      },
      /**
       * Evaluates the stop loss products and returns a string based on the products overall states.
       *
       * @returns {string}
       */
      stopLossProgress() {
        const stopLossProducts = this.products.filter((product) => (
          this.$TF.Product.isStopLoss(product)));
        let progressIcon = 'not-started';

        if (
          stopLossProducts.some((product) => (
            product.inforce_product.valid_plan_design
            || product.inforce_product.valid_rate_structure))
        ) {
          const isFull = stopLossProducts.every((product) => (
            product.inforce_product.valid_plan_design
            && product.inforce_product.valid_rate_structure));

          progressIcon = isFull
            ? 'full'
            : 'half';
        }

        return progressIcon;
      },
    },
    /**
     * Go through allProducts and created some dynamic props
     * so we don't have to handle so much in `data.allProducts`.
     * This creates the `products` array to pass to `<TfProductSelector />`.
     */
    created() {
      this.allProducts.forEach((product, index) => {
        let validation = 'None';

        if (
          product.inforce_product.valid_plan_design
          || product.inforce_product.valid_rate_structure
        ) {
          validation = product.inforce_product.valid_plan_design
            && product.inforce_product.valid_rate_structure
            ? 'Full'
            : 'Half';
        }

        this.products.push({
          ...product,
          ...{
          validation,
          id: index + 1,
          position: index + 1,
        },
        });

        this.validateProduct(validation, index);
      });
    },
    methods: {
      /**
       * Updates the `payloads.emitted` object to the latest payload for display only purposes.
       *
       * @param {string} name
       * @param {object} payload
       */
      onEmit(name, payload) {
        this.payloads.emitted = { name, payload };
      },
      /**
       * Updates the validation and products state based on what the `value`` param is.
       *
       * @param {string} value
       * @param {number} index
       */
      validateProduct(value, index) {
        this.products[index].inforce_product = {
          valid_plan_design: ['Full', 'Half'].includes(value),
          valid_rate_structure: value === 'Full',
        };

        this.products[index].state = value === 'Full' ? 'complete' : 'not-complete';
      },
    },
  };
</script>

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

  .flex {
    display: flex;
    justify-content: space-between;
  }

  #container-actions {
    border: 1px solid $tf-extra-light-gray-1;

    div {
      flex: 1;
      padding: 20px;

      &:nth-child(even) {
        background: $tf-extra-light-gray-1;
      }
    }
  }

  #container-product-selector {
    width: 400px;
    margin-right: 40px;
  }

  .container-append-slot {
    display: flex;
    align-items: center;
    width: 16px;
    margin-left: 5px;
  }

  .custom-empty {
    display: block;
    width: 16px;
    height: 16px;
    overflow: hidden;
    border: 2px solid $tf-light-gray;
    border-radius: 100%;
    box-sizing: border-box;

    &.half {
      &:after {
        display: block;
        margin-left: 6px;
        background: $tf-orange;
        width: 14px;
        height: 14px;
        content: '';
      }
    }

    &.square {
      border-radius: 2px;
    }
  }

  // Checkbox styles
  .el-checkbox {
    margin-right: 10px;
  }
</style>
