import '@things-factory/barcode-ui'
import { SingleColumnFormStyles } from '@things-factory/form-ui'
import '@things-factory/grist-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { client } from '@things-factory/shell'
import gql from 'graphql-tag'
import { css, html } from 'lit-element'
import { ORDER_TYPES } from '../../constants'
import { VasTemplate } from './vas-template'

//vas --inbound
class VasUnpack extends localize(i18next)(VasTemplate) {
  static get styles() {
    return [
      SingleColumnFormStyles,
      css`
        :host {
          display: flex;
          flex: 1;
          flex-direction: column;
        }
        .container {
          display: flex;
          flex-direction: column;
          flex: 1;
          margin: 0px 20px;
        }
        data-grist {
          flex: 1;
        }
      `
    ]
  }

  static get properties() {
    return {
      record: Object,
      targetInfo: Object,
      packingTypes: Array,
      isExecuting: Boolean,
      config: Object,
      parentProduct: Object,
      childProducts: Object,
      _palletId: String
    }
  }

  render() {
    return html`
      <div class="container">
        <form
          id="unpack-info-form"
          class="single-column-form"
          @submit="${e => e.preventDefault()}"
          @keypress="${e => {
            if (e.keyCode === 13) this.unpack()
          }}"
        >
          <fieldset>
            <legend>${i18next.t('title.unpack')}</legend>

            ${this.isExecuting && this.orderType === ORDER_TYPES.VAS_ORDER.value
              ? html`
                  <label>${i18next.t('label.lot_id')}</label>
                  <barcode-scanable-input
                    name="palletId"
                    .value=${this._palletId}
                    without-enter
                    custom-input
                  ></barcode-scanable-input>

                  <label>${i18next.t('label.location')}</label>
                  <barcode-scanable-input name="locationCode" without-enter custom-input></barcode-scanable-input>
                `
              : ''}

            <label>${i18next.t('label.product')}</label>
            <select
              id="child-product-selector"
              @change="${e => {
                let index = e.currentTarget.selectedIndex - 1
                this.unpackQtyInput.value = index >= 0 ? this.childProducts[index].bundleQty : ''
                this.unpackUomValueInput.value = index >= 0 ? this.childProducts[index].primaryValue : ''
              }}"
            >
              <option></option>
              ${this.childProducts.map(
                item =>
                  html`<option value="${item.id}" ?selected="${this._getOperationGuideData('productId') === item.id}">
                    ${item.sku + '(' + item.name + ')'}
                  </option>`
              )}
            </select>

            <label>${i18next.t('label.unpack_qty')}</label>
            <input name="unpack-qty" type="number" min="1" value="${this._getOperationGuideData('unpackQty') || 0}" />

            <label>${i18next.t('label.unpack_uom_value')}</label>
            <input
              name="unpack-uom-value"
              type="number"
              min="0.01"
              value="${this._getOperationGuideData('unpackUomValue') || 0}"
            />
          </fieldset>
        </form>
      </div>
    `
  }

  constructor() {
    super()
    this.packingTypes = []
    this.config = {}
    this.parentProduct = []
    this.childProducts = []
  }

  get contextButtons() {
    return []
  }

  get form() {
    return this.shadowRoot.querySelector('form#unpack-info-form')
  }

  get transactions() {
    return []
  }

  get revertTransactions() {
    return []
  }

  get data() {
    return {
      parentProductId: this.targetInfo[0].target.productId,
      productId: this.childProductSelector.value,
      unpackQty: Number(this.unpackQtyInput.value) || '',
      unpackUomValue: Number(this.unpackUomValueInput.value) || ''
    }
  }

  get childProductSelector() {
    return this.shadowRoot.querySelector('select#child-product-selector')
  }

  get palletInput() {
    return this.shadowRoot.querySelector('barcode-scanable-input[name=palletId]').shadowRoot.querySelector('input')
  }

  get locationInput() {
    return this.shadowRoot.querySelector('barcode-scanable-input[name=locationCode]').shadowRoot.querySelector('input')
  }

  get unpackQtyInput() {
    return this.shadowRoot.querySelector('input[name=unpack-qty]')
  }

  get unpackUomValueInput() {
    return this.shadowRoot.querySelector('input[name=unpack-uom-value]')
  }

  async firstUpdated() {
    await this._fetchParentProduct()
    await this._fetchChildProducts()
  }

  async init() {
    await this.updateComplete
    this.isExecuting = !this.record.completed
  }

  async _fetchParentProduct() {
    let filters = [
      {
        name: 'id',
        operator: 'eq',
        value: this.targetInfo ? this.targetInfo[0].target.productId : this.record.operationGuide.data.parentProductId
      }
    ]

    const response = await client.query({
      query: gql`
        query products($filters: [Filter!]) {
          products(filters: $filters) {
            items {
              id
              name
              description
              sku
              bundleQty
              primaryUnit
              primaryValue
            }
            total
          }
        }
      `,
      variables: {
        filters
      }
    })

    if (response && !response.errors) {
      this.parentProduct = response.data.products.items
    }
  }

  async _fetchChildProducts() {
    let filters = [{ name: 'parentProductRefId', operator: 'eq', value: this.parentProduct[0].id }]

    const response = await client.query({
      query: gql`
        query products($filters: [Filter!]) {
          products(filters: $filters) {
            items {
              id
              name
              description
              sku
              bundleQty
              primaryUnit
              primaryValue
            }
            total
          }
        }
      `,
      variables: { filters }
    })

    if (response && !response.errors) {
      this.childProducts = response.data.products.items
    }
  }

  async unpack() {
    try {
      this._checkUnpackable()
      await client.mutate({
        mutation: gql`
          mutation unpacking(
            $worksheetDetailName: String!
            $childProductId: String!
            $unpackQty: Int!
            $unpackUomValue: Float!
            $palletId: String
            $locationName: String
          ) {
            unpacking(
              worksheetDetailName: $worksheetDetailName
              childProductId: $childProductId
              unpackQty: $unpackQty
              unpackUomValue: $unpackUomValue
              palletId: $palletId
              locationName: $locationName
            )
          }
        `,
        variables: {
          worksheetDetailName: this.record.name,
          childProductId: this.childProductSelector.value,
          unpackQty: parseInt(this.unpackQtyInput.value || 0),
          unpackUomValue: parseFloat(this.unpackUomValueInput.value || 0),
          palletId: this.palletInput.value,
          locationName: this.locationInput.value
        }
      })

      this.dispatchEvent(
        new CustomEvent('completed', {
          bubbles: true,
          composed: true
        })
      )
    } catch (e) {
      this._showToast(e)
    }
  }

  _checkUnpackable() {
    if (!this.childProductSelector.value) {
      this.childProductSelector.select()
      throw new Error(i18next.t('text.product_is_not_selected'))
    }

    if (!this.unpackQtyInput.value) {
      this.unpackQtyInput.value = this.record.operationGuide.data.unpackQty
      this.unpackQtyInput.focus()
      throw new Error(i18next.t('text.unpack_qty_is_empty'))
    }

    if (!this.unpackUomValueInput.value) {
      this.unpackUomValueInput.value = this.record.operationGuide.data.unpackUomValue
      this.unpackUomValueInput.focus()
      throw new Error(i18next.t('text.unpack_uom_value_is_empty'))
    }
  }

  async validateAdjust() {
    const unpackQty = Number(this.unpackQtyInput.value)
    if (unpackQty <= 0) throw new Error(i18next.t('text.unpack_qty_should_be_positive'))

    const unpackUomValue = Number(this.unpackUomValueInput.value)
    if (unpackUomValue <= 0) throw new Error(i18next.t('text.unpack_uom_value_should_be_positive'))
  }
}

window.customElements.define('vas-unpack', VasUnpack)
