import '@things-factory/barcode-ui'
import { SingleColumnFormStyles } from '@things-factory/form-ui'
import { client, CustomAlert } from '@things-factory/shell'
import gql from 'graphql-tag'
import { i18next, localize } from '@things-factory/i18n-base'
import { css, html, LitElement } from 'lit-element'

class RelocateInventoryPopup extends localize(i18next)(LitElement) {
  static get properties() {
    return {
      config: Object,
      data: Object
    }
  }

  static get styles() {
    return [
      SingleColumnFormStyles,
      css`
        :host {
          padding: 10px;
          display: flex;
          flex-direction: column;
          overflow-x: overlay;
          background-color: var(--main-section-background-color);
        }
        .button-container {
          padding: var(--button-container-padding);
          margin: var(--button-container-margin);
          text-align: var(--button-container-align);
          background-color: var(--button-container-background);
          height: var(--button-container-height);
        }
        .button-container button {
          background-color: var(--button-container-button-background-color);
          border-radius: var(--button-container-button-border-radius);
          height: var(--button-container-button-height);
          border: var(--button-container-button-border);
          margin: var(--button-container-button-margin);
          padding: var(--button-padding);
          color: var(--theme-white-color);
          font: var(--button-font);
          text-transform: var(--button-text-transform);
        }
        .button-container button:hover,
        .button-container button:active {
          background-color: var(--button-background-focus-color);
        }
        .button-container > barcode-scanable-input {
          margin: auto;
        }
      `
    ]
  }

  async firstUpdated() {
    await this.updateComplete

    this.focusOnLocationInput()
  }

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

  render() {
    return html`
      <form
        id="input-form"
        class="single-column-form"
        @keypress="${async e => {
          if (e.keyCode === 13) {
            e.preventDefault()
            this._relocateInv()
          }
        }}"
      >
        <fieldset>
          <legend>${i18next.t('title.scan_area')}</legend>
          <label>${i18next.t('label.location')}</label>
          <barcode-scanable-input name="location" custom-input></barcode-scanable-input>
        </fieldset>
      </form>
      <div class="button-container">
        <mwc-button raised @click="${this._relocateInv}" label="${i18next.t('button.relocate')}"></mwc-button>
      </div>
    `
  }

  focusOnLocationInput() {
    this.locationInput.focus()
  }

  async _relocateInv() {
    try {
      await this._validateInput()

      let { inspectedQty, inspectedUomValue, cartonId, palletId, productDetailId, batchId, locationId } =
        this.currentCard
      inspectedQty = Number(inspectedQty)
      inspectedUomValue = cartonId && palletId ? inspectedQty : Number(inspectedUomValue)

      const result = await CustomAlert({
        title: i18next.t('title.are_you_sure'),
        text: i18next.t('button.relocate'),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (!result.value) {
        return
      }

      const variables = {
        worksheetDetailName: this.currentCard.name,
        inspectedBatchNo: this.currentCard.inspectedBatchNo,
        inspectedQty: inspectedQty,
        inspectedUomValue: inspectedUomValue,
        inspectedLocationName: this.locationInput.value
      }
      let response

      if (!this.enableCartonLabel) {
        response = await client.mutate({
          mutation: gql`
            mutation relocateInventory(
              $worksheetDetailName: String!
              $inspectedBatchNo: String!
              $inspectedQty: Float!
              $inspectedUomValue: Float!
              $inspectedLocationName: String!
            ) {
              relocateInventory(
                worksheetDetailName: $worksheetDetailName
                inspectedBatchNo: $inspectedBatchNo
                inspectedQty: $inspectedQty
                inspectedUomValue: $inspectedUomValue
                inspectedLocationName: $inspectedLocationName
              )
            }
          `,
          variables: {
            worksheetDetailName: this.currentCard.name,
            inspectedBatchNo: this.currentCard.inspectedBatchNo,
            inspectedQty: Number(this.currentCard.inspectedQty),
            inspectedUomValue: inspectedUomValue,
            inspectedLocationName: this.locationInput.value
          }
        })
      } else {
        response = await client.mutate({
          mutation: gql`
            mutation relocateInventoryCarton(
              $productDetailId: String!
              $cartonId: String!
              $batchId: String!
              $locationId: String!
              $inspectedBatchNo: String!
              $inspectedQty: Float!
              $inspectedUomValue: Float!
              $inspectedLocationName: String!
            ) {
              relocateInventoryCarton(
                productDetailId: $productDetailId
                cartonId: $cartonId
                batchId: $batchId
                locationId: $locationId
                inspectedBatchNo: $inspectedBatchNo
                inspectedQty: $inspectedQty
                inspectedUomValue: $inspectedUomValue
                inspectedLocationName: $inspectedLocationName
              )
            }
          `,
          variables: {
            productDetailId: this.currentCard.productDetailId,
            cartonId: this.currentCard.cartonId,
            batchId: this.currentCard.batchId,
            locationId: this.currentCard.locationId,
            inspectedBatchNo: this.currentCard.inspectedBatchNo,
            inspectedQty: Number(this.currentCard.inspectedQty),
            inspectedUomValue: inspectedUomValue,
            inspectedLocationName: this.locationInput.value
          }
        })
      }
      this.dispatchEvent(new CustomEvent('relocate', {}))
      this._showToast({ message: i18next.t('text.the_inventory_has_been_relocated') })
    } catch (e) {
      this._showToast(e)
    }
  }

  async _validateInput() {
    const locationName = this.locationInput.value
    if (!locationName) {
      this.selectOnInput(this.locationInput)
      throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('label.location') } }))
    } else {
      const foundLocation = await this._fetchLocation(locationName)
      if (!foundLocation) {
        throw new Error(i18next.t('text.location_not_found'))
      }
    }

    if (this.currentCard.locationName === this.locationInput.value) {
      throw new Error(`You can't relocate to the same location.`)
    }
  }

  async _fetchLocation(locationName) {
    if (locationName) {
      const response = await client.query({
        query: gql`
          query location($name: String!) {
            location(name: $name) {
              id
              name
              zone
              row
              column
              shelf
              type
            }
          }
        `,
        variables: { name: locationName }
      })

      if (!response.errors) {
        return response.data.location
      }
    }
  }

  selectOnInput(input) {
    setTimeout(() => input.select(), 100)
  }

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

window.customElements.define('relocate-inventory-popup', RelocateInventoryPopup)
