import '@things-factory/form-ui'
import '@things-factory/grist-ui'
import '@things-factory/import-ui'
import './inventory-by-product-detail'

import gql from 'graphql-tag'
import { css, html } from 'lit-element'

import { MultiColumnFormStyles } from '@things-factory/form-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client, PageView } from '@things-factory/shell'
import { ScrollbarStyles } from '@things-factory/styles'
import { isMobileDevice } from '@things-factory/utils'
import { applyParamsToFields } from '../../util'

class InventoryByProduct extends localize(i18next)(PageView) {
  static get properties() {
    return {
      _checkedBoxes: Array,
      _searchFields: Array,
      config: Object,
      data: Object
    }
  }

  static get styles() {
    return [
      ScrollbarStyles,
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
        }

        search-form {
          overflow: visible;
        }

        search-form.search-form {
          border-bottom: none;
        }

        data-grist {
          overflow-y: auto;
          flex: 1;
        }

        input[type='checkbox'].toggle {
          font-size: 13px;
          -webkit-appearance: none;
          -moz-appearance: none;
          appearance: none;
          width: 3.5em;
          height: 1.5em;
          border: 0.5px solid #3a5877;
          border-radius: 3em;
          position: relative;
          cursor: pointer;
          outline: none;
          -webkit-transition: all 0.2s ease-in-out;
          transition: all 0.2s ease-in-out;
          padding: 0px 0px;
        }

        input[type='checkbox'].toggle:checked {
          background: #b8e0e1;
          border: 0.5px solid #3a5877;
        }

        input[type='checkbox'].toggle:after {
          padding-top: 0;
          position: absolute;
          content: '';
          width: 1.4em;
          height: 1.4em;
          border-radius: 50%;
          background: #3a5877;
          -webkit-box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.3);
          box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.3);
          -webkit-transform: scale(0.7);
          transform: scale(0.7);
          left: 0;
          -webkit-transition: all 0.2s ease-in-out;
          transition: all 0.2s ease-in-out;
        }

        input[type='checkbox'].toggle:checked:after {
          left: calc(100% - 1.4em);
        }
      `
    ]
  }

  constructor() {
    super()
    this._checkedBoxes = []
    this._showTotalUom = false
    // count holds value to determine if data needs to be fetch from database.
    this.count = 0
    this.responseArr
  }

  render() {
    return html`
      <search-form id="search-form" .fields=${this._searchFields} @submit=${e => this.dataGrist.fetch()}></search-form>
      <form name="uom-selection" class="multi-column-form" style="margin-top: 0px">
        <fieldset>
          <legend>${i18next.t('title.column_selection')}</legend>
        </fieldset>
        <input id="uomToggle" type="checkbox" class="toggle" @change="${this._handleShowTotalUomChange}" />
        <label for="showTotalUom">${i18next.t('field.show_total_uom')}</label>
      </form>

      <data-grist
        .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
        .config=${this.config}
        .fetchHandler="${this.fetchHandler.bind(this)}"
      ></data-grist>
    `
  }

  getResponseArr() {
    return this.responseArr
  }

  get context() {
    return {
      title: i18next.t('title.inventory_by_product'),
      exportable: {
        name: i18next.t('title.inventory_by_product'),
        data: this._exportableData.bind(this)
      },
      help: 'operato-wms/inventory/inventory-by-product'
    }
  }

  get searchForm() {
    return this.shadowRoot.querySelector('search-form')
  }

  get _availabletockCheckbox() {
    return this.searchForm.shadowRoot.querySelector('input[name=availableStock]')
  }

  get dataGrist() {
    this.count = 0
    return this.shadowRoot.querySelector('data-grist')
  }

  pageUpdated(changes, lifecycle) {
    if (this.active) {
      if (this._availabletockCheckbox && !this._checkedBoxes.length)
        this._checkedBoxes = [this._availabletockCheckbox, { name: 'temp', checked: false }]

      let { params } = lifecycle
      if (params && this._searchFields) {
        const updatedFields = applyParamsToFields(this._searchFields, params)
        this._searchFields = updatedFields
        const searchForm = this.searchForm
        if (searchForm) {
          searchForm.fields = updatedFields
        }
      }

      this.dataGrist.fetch()
    }
  }

  _handleShowTotalUomChange(event) {
    this._showTotalUom = event.target.checked
    this.count = 1
    this.config = this.getConfig()
    this.requestUpdate()
  }

  async pageInitialized() {
    this.count = 0
    const partners = await this._fetchPartners()
    this._searchFields = [
      {
        label: i18next.t('field.company'),
        name: 'bizplace',
        type: 'select',
        options:
          partners?.length == 1
            ? [
                {
                  name: `${partners[0].name} ${partners[0].description ? `(${partners[0].description})` : ''}`,
                  value: partners[0].id
                }
              ]
            : [
                { value: '' },
                ...partners
                  .map(partner => {
                    return {
                      name: `${partner.name} ${partner.description ? `(${partner.description})` : ''}`,
                      value: partner.id
                    }
                  })
                  .sort(this._compareValues('name', 'asc'))
              ],
        props: { searchOper: 'eq' }
      },
      {
        label: i18next.t('field.product_info'),
        name: 'product',
        type: 'string',
        props: { searchOper: 'eq' }
      },
      {
        label: i18next.t('field.packing_type'),
        name: 'packingType',
        type: 'string',
        props: { searchOper: 'eq' }
      },
      {
        label: i18next.t('field.available_qty_only'),
        name: 'availableStock',
        type: 'checkbox',
        value: true,
        props: { searchOper: 'eq' },
        handlers: { change: this._updateSearchInputState.bind(this, 'availableStock') },
        attrs: ['indeterminate']
      },
      {
        label: i18next.t('field.low_on_stock'),
        name: 'lowStock',
        type: 'checkbox',
        value: false,
        props: { searchOper: 'eq' },
        handlers: { change: this._updateSearchInputState.bind(this, 'lowStock') }
      },
      {
        label: i18next.t('field.over_stock'),
        name: 'overStock',
        type: 'checkbox',
        value: false,
        props: { searchOper: 'eq' },
        handlers: { change: this._updateSearchInputState.bind(this, 'overStock') }
      },
      {
        label: i18next.t('field.quarantine_stock_only'),
        name: 'quarantineStock',
        type: 'checkbox',
        value: false,
        props: { searchOper: 'eq' },
        handlers: { change: this._updateSearchInputState.bind(this, 'quarantineStock') }
      },
      {
        label: i18next.t('field.reserve_stock_only'),
        name: 'reserveStock',
        type: 'checkbox',
        value: false,
        props: { searchOper: 'eq' },
        handlers: { change: this._updateSearchInputState.bind(this, 'reserveStock') }
      }
    ]
    this.config = this.getConfig()
  }

  getConfig() {
    return {
      rows: { appendable: false, selectable: { multiple: true } },
      list: { fields: ['bizplace', 'sku', 'name', 'description', 'type', 'qty'] },
      pagination: { limit: 100, pages: [100, 200, 500, 1000] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        { type: 'gutter', gutterName: 'row-selector', multiple: true },
        {
          type: 'gutter',
          gutterName: 'button',
          icon: 'reorder',
          handlers: {
            click: this._showInventoryInfo.bind(this)
          }
        },
        {
          type: 'object',
          name: 'bizplace',
          header: i18next.t('field.company'),
          imex: { header: i18next.t('field.company'), key: 'bizplace', width: 50, type: 'string' },
          sortable: true,
          label: true,
          width: 250
        },
        {
          type: 'string',
          name: 'sku',
          imex: { header: i18next.t('field.sku'), key: 'sku', width: 30, type: 'string' },
          header: i18next.t('field.sku'),
          label: true,
          width: 130
        },
        {
          type: 'string',
          name: 'name',
          imex: { header: i18next.t('field.name'), key: 'name', width: 50, type: 'string' },
          header: i18next.t('field.name'),
          label: true,
          width: 200
        },
        {
          type: 'string',
          name: 'brand',
          imex: { header: i18next.t('field.brand'), key: 'brand', width: 30, type: 'string' },
          header: i18next.t('field.brand'),
          label: true,
          width: 100
        },
        {
          type: 'string',
          name: 'description',
          imex: { header: i18next.t('field.product_description'), key: 'description', width: 50, type: 'string' },
          header: i18next.t('field.description'),
          label: true,
          width: 300
        },
        {
          type: 'string',
          name: 'packingType',
          imex: { header: i18next.t('field.packing_type'), key: 'packingType', width: 25, type: 'string' },
          header: i18next.t('field.packing_type'),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxUnit1',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_unit_x', { state: { x: '1' } }),
            key: 'auxUnit1',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_unit_x', { state: { x: '1' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxValue1',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_value_x', { state: { x: '1' } }),
            key: 'auxValue1',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_value_x', { state: { x: '1' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxUnit2',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_unit_x', { state: { x: '2' } }),
            key: 'auxUnit2',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_unit_x', { state: { x: '2' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxValue2',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_value_x', { state: { x: '2' } }),
            key: 'auxValue2',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_value_x', { state: { x: '2' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxUnit3',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_unit_x', { state: { x: '3' } }),
            key: 'auxUnit3',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_unit_x', { state: { x: '3' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxValue3',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_value_x', { state: { x: '3' } }),
            key: 'auxValue3',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_value_x', { state: { x: '3' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxUnit4',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_unit_x', { state: { x: '4' } }),
            key: 'auxUnit4',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_unit_x', { state: { x: '4' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxValue4',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_value_x', { state: { x: '4' } }),
            key: 'auxValue4',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_value_x', { state: { x: '4' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxUnit5',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_unit_x', { state: { x: '5' } }),
            key: 'auxUnit5',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_unit_x', { state: { x: '5' } }),
          label: true,
          width: 150
        },
        {
          type: 'string',
          name: 'auxValue5',
          hidden: true,
          imex: {
            header: i18next.t('field.aux_value_x', { state: { x: '5' } }),
            key: 'auxValue5',
            width: 25,
            type: 'string'
          },
          header: i18next.t('field.aux_value_x', { state: { x: '5' } }),
          label: true,
          width: 150
        },
        {
          type: 'float',
          name: 'minQty',
          imex: {
            header: i18next.t('field.min_qty'),
            key: 'minQty',
            width: 20,
            type: 'float'
          },
          header: i18next.t('field.min_qty'),
          label: true,
          width: 80
        },
        {
          type: 'float',
          name: 'uomValueMinQty',
          imex: {
            header: i18next.t('field.total_uom_value_min'),
            key: 'uomValueMinQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_min'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'maxQty',
          imex: { header: i18next.t('field.max_qty'), key: 'maxQty', width: 20, type: 'integer' },
          header: i18next.t('field.max_qty'),
          label: true,
          width: 80
        },
        {
          type: 'integer',
          name: 'uomValueMaxQty',
          imex: {
            header: i18next.t('field.total_uom_value_max'),
            key: 'uomValueTransferQty',
            width: 60,
            type: 'integer'
          },
          header: i18next.t('field.total_uom_value_max'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'qty',
          imex: { header: i18next.t('field.shelf_qty'), key: 'qty', width: 20, type: 'integer' },
          header: i18next.t('field.shelf_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueShelfQty',
          imex: {
            header: i18next.t('field.total_uom_value_shelf'),
            key: 'uomValueShelfQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_shelf'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'draftQty',
          imex: { header: `${i18next.t('field.draft_qty')}(-)`, key: 'draftQty', width: 20, type: 'integer' },
          header: `${i18next.t('field.draft_qty')}(-)`,
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueDraftQty',
          imex: {
            header: i18next.t('field.total_uom_value_draft'),
            key: 'uomValueDraftQty',
            width: 60,
            type: 'integer'
          },
          header: i18next.t('field.total_uom_value_draft'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'releaseQty',
          imex: { header: `${i18next.t('field.release_qty')}(-)`, key: 'releaseQty', width: 20, type: 'integer' },
          header: `${i18next.t('field.release_qty')}(-)`,
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueReleaseQty',
          imex: {
            header: i18next.t('field.total_uom_value_release'),
            key: 'uomValueReleaseQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_release'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'insufficientQty',
          imex: { header: i18next.t('field.insufficient_qty'), key: 'insufficientQty', width: 20, type: 'integer' },
          header: i18next.t('field.insufficient_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueInsufficientQty',
          imex: {
            header: i18next.t('field.total_uom_value_insufficient'),
            key: 'uomValueInsufficientQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_insufficient'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'putawayQty',
          imex: { header: i18next.t('field.putaway_qty'), key: 'putawayQty', width: 20, type: 'integer' },
          header: i18next.t('field.putaway_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValuePutawayQty',
          imex: {
            header: i18next.t('field.total_uom_value_putaway'),
            key: 'uomValuePutawayQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_putaway'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'availableQty',
          imex: { header: i18next.t('field.available_qty'), key: 'availableQty', width: 20, type: 'integer' },
          header: i18next.t('field.available_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueAvailableQty',
          imex: {
            header: i18next.t('field.total_uom_value_available'),
            key: 'uomValueAvailableQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_available'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'quarantineQty',
          imex: { header: i18next.t('field.quarantine_qty'), key: 'quarantineQty', width: 20, type: 'integer' },
          header: i18next.t('field.quarantine_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueQuarantineQty',
          imex: {
            header: i18next.t('field.total_uom_value_quarantine'),
            key: 'uomValueQuarantineQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_quarantine'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'reserveQty',
          imex: { header: i18next.t('field.reserve_qty'), key: 'reserveQty', width: 20, type: 'integer' },
          header: i18next.t('field.reserve_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueReserveQty',
          imex: {
            header: i18next.t('field.total_uom_value_reserve'),
            key: 'uomValueReserveQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_reserve'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'warehouseQty',
          imex: { header: i18next.t('field.warehouse_qty'), key: 'warehouseQty', width: 20, type: 'integer' },
          header: i18next.t('field.warehouse_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueWarehouseQty',
          imex: {
            header: i18next.t('field.total_uom_value_warehouse'),
            key: 'uomValueWarehouseQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_warehouse'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'obsoleteQty',
          imex: { header: i18next.t('field.obsolete_qty'), key: 'obsoleteQty', width: 20, type: 'integer' },
          header: i18next.t('field.obsolete_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueObsoleteQty',
          imex: {
            header: i18next.t('field.total_uom_value_obsolete'),
            key: 'uomValueObsoleteQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_obsolete'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'damageQty',
          imex: { header: i18next.t('field.damage_qty'), key: 'damageQty', width: 20, type: 'integer' },
          header: i18next.t('field.damage_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueDamageQty',
          imex: {
            header: i18next.t('field.total_uom_value_damage'),
            key: 'uomValueDamageQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_damage'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'storageQty',
          imex: { header: i18next.t('field.storage_qty'), key: 'storageQty', width: 20, type: 'integer' },
          header: i18next.t('field.storage_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueStorageQty',
          imex: {
            header: i18next.t('field.total_uom_value_storage'),
            key: 'uomValueStorageQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_storage'),
          width: 120,
          hidden: !this._showTotalUom
        },
        {
          type: 'float',
          name: 'transferQty',
          imex: { header: i18next.t('field.transfer_qty'), key: 'transferQty', width: 20, type: 'integer' },
          header: i18next.t('field.transfer_qty'),
          label: true,
          width: 120
        },
        {
          type: 'float',
          name: 'uomValueTransferQty',
          imex: {
            header: i18next.t('field.total_uom_value_transfer'),
            key: 'uomValueTransferQty',
            width: 60,
            type: 'float'
          },
          header: i18next.t('field.total_uom_value_transfer'),
          width: 120,
          hidden: !this._showTotalUom
        }
      ]
    }
  }

  async fetchHandler({ page, limit, sorters = [] }) {
    let records = []
    let total

    if (this.count === 1) {
      records = this.responseArr
      total = this.responseArr.length
    } else {
      const response = await client.query({
        query: gql`
          query inventoriesByProduct($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
            inventoriesByProduct(filters: $filters, pagination: $pagination, sortings: $sortings) {
              items {
                product {
                  id
                  sku
                  brand
                  name
                  description
                  minQty
                  maxQty
                  auxUnit1
                  auxValue1
                  auxUnit2
                  auxValue2
                  auxUnit3
                  auxValue3
                  auxUnit4
                  auxValue4
                  auxUnit5
                  auxValue5
                }
                bizplace {
                  id
                  name
                }
                packingType
                averageUnitCost
                qty
                putawayQty
                availableQty
                insufficientQty
                releaseQty
                quarantineQty
                reserveQty
                draftQty
                warehouseQty
                obsoleteQty
                damageQty
                storageQty
                transferQty
                uomValue
              }
              total
            }
          }
        `,
        variables: { filters: await this.searchForm.getQueryFilters(), pagination: { page, limit }, sortings: sorters }
      })

      if (!response.errors) {
        total = response.data.inventoriesByProduct.total || 0
        records = (response.data.inventoriesByProduct.items || []).map(item => {
          // changed to direct assign instead of spread ...item, ...item.product to improve performance
          let record = item.product
          record.packingType = item.packingType
          record.averageUnitCost = item.averageUnitCost
          record.putawayQty = item.putawayQty
          record.qty = item.qty
          record.availableQty = item.availableQty
          record.insufficientQty = item.insufficientQty
          record.releaseQty = item.releaseQty
          record.quarantineQty = item.quarantineQty
          record.reserveQty = item.reserveQty
          record.warehouseQty = item.warehouseQty
          record.draftQty = item.draftQty
          record.bizplace = item.bizplace
          record.obsoleteQty = item.obsoleteQty
          record.transferQty = item.transferQty
          record.storageQty = item.storageQty
          record.damageQty = item.damageQty
          record.uomValue = item.uomValue

          record.uomValueMinQty = record.uomValue * record.minQty
          record.uomValueMaxQty = record.uomValue * record.maxQty
          record.uomValueShelfQty = record.uomValue * record.qty
          record.uomValueDraftQty = record.uomValue * record.draftQty
          record.uomValueReleaseQty = record.uomValue * record.releaseQty
          record.uomValueInsufficientQty = record.uomValue * record.insufficientQty
          record.uomValuePutawayQty = record.uomValue * record.putawayQty
          record.uomValueAvailableQty = record.uomValue * record.availableQty
          record.uomValueQuarantineQty = record.uomValue * record.quarantineQty
          record.uomValueReserveQty = record.uomValue * record.reserveQty
          record.uomValueWarehouseQty = record.uomValue * record.warehouseQty
          record.uomValueObsoleteQty = record.uomValue * record.obsoleteQty
          record.uomValueDamageQty = record.uomValue * record.damageQty
          record.uomValueStorageQty = record.uomValue * record.storageQty
          record.uomValueTransferQty = record.uomValue * record.transferQty

          return record
        })
        this.responseArr = records
      }
      return { records, total }
    }
  }

  get _columns() {
    return this.config.columns
  }

  _updateSearchInputState(fieldName) {
    this.count = 0
    const targetField = this.searchForm.shadowRoot.querySelector(`input[name=${fieldName}]`)

    if (targetField.checked) {
      // clear all previously checked fields
      this._checkedBoxes[1].checked = false
      this._checkedBoxes[0].checked = false

      const tempIdx = this._checkedBoxes.findIndex(cb => cb.name == 'temp')

      if (fieldName == 'lowStock' || fieldName == 'overStock') {
        const idx = this._checkedBoxes.findIndex(cb => cb.name == (fieldName == 'lowStock' ? 'overStock' : 'lowStock'))
        if (idx == 1) {
          this._checkedBoxes[1] = targetField
        } else {
          if (tempIdx == 1) {
            this._checkedBoxes[1] = targetField
          } else {
            this._checkedBoxes[0] = this._checkedBoxes[1]
            this._checkedBoxes[1] = targetField
          }
        }
      } else {
        if (tempIdx == 1) {
          this._checkedBoxes[1] = targetField
        } else {
          this._checkedBoxes[0] = this._checkedBoxes[1]
          this._checkedBoxes[1] = targetField
        }
      }

      // reset all fields in _checkedBoxes array to TRUE
      this._checkedBoxes[1].checked = true
      this._checkedBoxes[0].checked = true
    } else {
      // replace unchecked field with default
      const idx = this._checkedBoxes.findIndex(cb => cb.name == fieldName)
      if (idx >= 0) this._checkedBoxes[idx] = { name: 'temp', checked: false }
    }
  }

  async _fetchPartners() {
    const filters = []
    const response = await client.query({
      query: gql`
        query partnersBizplaces($filters: [Filter!]) {
          partnersBizplaces(filters: $filters) {
            items {
              id
              name
              description
            }
          }
        }
      `,
      variables: { filters }
    })

    if (!response.errors) {
      return response.data.partnersBizplaces.items
    }
  }

  _compareValues(key, order = 'asc') {
    return function innerSort(a, b) {
      if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
        return 0
      }

      const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
      const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]

      let comparison = 0
      if (varA > varB) {
        comparison = 1
      } else if (varA < varB) {
        comparison = -1
      }
      return order === 'desc' ? comparison * -1 : comparison
    }
  }

  async _exportableData() {
    try {
      let records = []
      if (this.dataGrist.selected && this.dataGrist.selected.length > 0) {
        records = this.dataGrist.selected
      } else {
        const bizplaceFilters = (await this.searchForm.getQueryFilters()).filter(x => x.name === 'bizplace')
        if (bizplaceFilters.length == 0) {
          throw new Error(`Please select a customer for export.`)
        }
        records = (await this.fetchHandler({ page: 1, limit: 9999999 })).records || []
      }

      var headerSetting = this.dataGrist._config.columns
        .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
        .map(column => {
          return column.imex
        })

      var data = records.map(item => {
        return {
          ...this._columns
            .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
            .reduce((record, column) => {
              record[column.imex.key] = column.imex.key
                .split('.')
                .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
              return record
            }, {}),
          id: item.id,
          name: item.name,
          sku: item.sku,
          brand: item.brand,
          description: item.description,
          packingType: item.packingType,
          bizplace: item.bizplace.name,
          qty: item.qty,
          putawayQty: item.putawayQty,
          minQty: item.minQty,
          maxQty: item.maxQty,
          insufficientQty: item.insufficientQty,
          availableQty: item.availableQty,
          releaseQty: item.releaseQty,
          quarantineQty: item.quarantineQty,
          reserveQty: item.reserveQty,
          draftQty: item.draftQty,
          warehouseQty: item.warehouseQty,
          obsoleteQty: item.obsoleteQty,
          damageQty: item.damageQty,
          storageQty: item.storageQty,
          transferQty: item.transferQty,
          auxUnit1: item.auxUnit1,
          auxValue1: item.auxValue1,
          auxUnit2: item.auxUnit2,
          auxValue2: item.auxValue2,
          auxUnit3: item.auxUnit3,
          auxValue3: item.auxValue3,
          auxUnit4: item.auxUnit4,
          auxValue4: item.auxValue4,
          auxUnit5: item.auxUnit5,
          auxValue5: item.auxValue5
          // averageUnitCost: item.averageUnitCost
        }
      })

      return { header: headerSetting, data: data }
    } catch (e) {
      this._showToast(e)
    }
  }

  _showInventoryInfo(columns, data, column, record, rowIndex) {
    openPopup(
      html`
        <inventory-by-product-detail
          .productId="${record.id}"
          .bizplaceId="${record.bizplace.id}"
        ></inventory-by-product-detail>
      `,
      {
        backdrop: true,
        size: 'large',
        title: `${record.name} ${record.description ? `(${record.description})` : ''}`
      }
    )
  }

  _showToast({ type, message }) {
    document.dispatchEvent(
      new CustomEvent('notify', {
        detail: {
          type,
          message
        }
      })
    )
  }
}

window.customElements.define('inventory-by-product', InventoryByProduct)
