import { MultiColumnFormStyles } 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 { isMobileDevice } from '@things-factory/utils'
import gql from 'graphql-tag'
import { css, html, LitElement } from 'lit-element'
import { ORDER_INVENTORY_STATUS, ORDER_TYPES } from '../../constants'

class ReturnOrderInventoryPopup extends localize(i18next)(LitElement) {
  static get properties() {
    return {
      _searchFields: Array,
      config: Object,
      data: Object,
      bizplaceId: String,
      _productName: String,
      inventoryData: Object,
      releaseOrderNo: String
    }
  }

  static get styles() {
    return [
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: hidden;
          background-color: white;
        }
        .container {
          flex: 1;
          display: flex;
          overflow-y: auto;
          min-height: 20vh;
        }

        .grist {
          display: flex;
          flex-direction: column;
          flex: 1;
          overflow-y: auto;
        }
        .grist h2 mwc-icon {
          vertical-align: middle;
          margin: var(--grist-title-icon-margin);
          font-size: var(--grist-title-icon-size);
          color: var(--grist-title-icon-color);
        }
        data-grist {
          overflow-y: hidden;
          flex: 1;
        }
        h2 {
          padding: var(--subtitle-padding);
          font: var(--subtitle-font);
          color: var(--subtitle-text-color);
          border-bottom: var(--subtitle-border-bottom);
        }
        .grist h2 {
          font: var(--grist-title-font);
        }
        .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);
        }
      `
    ]
  }

  render() {
    return html`
      <search-form id="search-form" .fields=${this.searchFields} @submit=${() => this.dataGrist.fetch()}></search-form>

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

      <div class="button-container">
        <mwc-button
          @click=${this._selectInventory.bind(this)}
          label="${i18next.t('button.confirm')}"
          raised
        ></mwc-button>
      </div>
    `
  }

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

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

  get releaseGoodNameInput() {
    return this.shadowRoot.querySelector('search-form').shadowRoot.querySelector('input[name=releaseGoodName]')
  }

  firstUpdated() {
    this.searchFields = [
      {
        name: 'releaseGoodName',
        label: i18next.t('field.order_info'),
        type: 'text',
        value: this.releaseOrderNo || this.releaseGoodNameInput || null,
        props: { searchOper: 'i_like' }
      },
      {
        name: 'productSKU',
        label: i18next.t('field.sku'),
        type: 'text',
        props: { searchOper: 'i_like' }
      }
    ]

    this.config = {
      list: {
        fields: [
          'releaseGoodName',
          'batchId',
          'productSKU',
          'productName',
          'packingType',
          'releaseQty',
          'releaseUomValue'
        ]
      },
      pagination: { pages: [10, 20, 50, 2500] },
      rows: { selectable: { multiple: true }, appendable: false },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        { type: 'gutter', gutterName: 'row-selector', multiple: true },
        {
          type: 'string',
          name: 'releaseGoodName',
          header: i18next.t('field.ro'),
          width: 150
        },
        {
          type: 'string',
          name: 'releaseGoodRefNo',
          header: i18next.t('field.ref_no'),
          width: 150
        },
        {
          type: 'string',
          name: 'releaseGoodRefNo2',
          header: i18next.t('field.ref_no_2'),
          width: 150
        },
        {
          type: 'string',
          name: 'releaseGoodRefNo3',
          header: i18next.t('field.ref_no_3'),
          width: 150
        },
        {
          type: 'string',
          name: 'palletId',
          header: i18next.t('field.inventory_list'),
          width: 120
        },
        {
          type: 'string',
          name: 'batchId',
          header: i18next.t('field.batch_id'),
          width: 120
        },
        {
          type: 'string',
          name: 'productSKU',
          header: i18next.t('field.sku'),
          width: 150
        },
        {
          type: 'string',
          name: 'productName',
          header: i18next.t('field.product_name'),
          width: 220
        },
        {
          type: 'string',
          name: 'productBrand',
          header: i18next.t('field.brand'),
          width: 120
        },
        {
          type: 'code',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          width: 120
        },
        {
          type: 'float',
          name: 'packingSize',
          header: i18next.t('field.packing_size'),
          width: 120
        },
        {
          type: 'float',
          name: 'releaseQty',
          header: i18next.t('field.return_qty'),
          width: 150
        },
        {
          type: 'float',
          name: 'releaseUomValue',
          header: i18next.t('field.release_uom_value'),
          width: 150
        }
      ]
    }
    this.dataGrist.fetch()
  }

  async fetchHandler({ page, limit, sorters = [{ name: 'batchId' }] }) {
    let filters = []

    if (this.inventoryData.records.length > 0) {
      filters = [
        {
          name: 'inventoryId',
          operator: 'notin',
          value: this.inventoryData.records.map(item => item.id)
        }
      ]
    }

    if (this.releaseOrderNo) {
      filters.push({
        name: 'releaseGoodName',
        operator: 'eq',
        value: this.releaseOrderNo
      })
    }

    filters.push(
      {
        name: 'status',
        operator: 'eq',
        value: ORDER_INVENTORY_STATUS.TERMINATED.value
      },
      {
        name: 'type',
        operator: 'eq',
        value: ORDER_TYPES.RELEASE_OF_GOODS.value
      },
      {
        name: 'bizplaceId',
        operator: 'eq',
        value: this.bizplaceId
      }
    )

    const response = await client.query({
      query: gql`
        query inventoriesByOrder($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
          inventoriesByOrder(filters: $filters, pagination: $pagination, sortings: $sortings) {
            items {
              id
              batchId
              inventory {
                id
              }
              productName
              productSKU
              productBrand
              packingType
              packingSize
              releaseUomValueWithUom
              releaseQty
              releaseUomValue
              palletId
              productId
              productDetailId
              releaseOrderId
              releaseGoodName
              isInventoryDecimal
              releaseGoodRefNo
              releaseGoodRefNo2
              releaseGoodRefNo3
            }
            total
          }
        }
      `,
      variables: {
        filters: [...filters, ...this.searchForm.queryFilters],
        pagination: { page, limit },
        sortings: sorters
      }
    })

    if (!response.errors) {
      return {
        total: response.data.inventoriesByOrder.total || 0,
        records: response.data.inventoriesByOrder.items || []
      }
    }
  }

  _selectInventory() {
    const selectedInventory = this.dataGrist.selected

    if (selectedInventory?.length) {
      this.dispatchEvent(
        new CustomEvent('selected', {
          detail: {
            selectedData: selectedInventory,
            releaseOrderNumber: this.releaseGoodNameInput.value
          }
        })
      )
      history.back()
    } else {
      document.dispatchEvent(
        new CustomEvent('notify', {
          detail: {
            message: i18next.t('label.please_select_an_item')
          }
        })
      )
    }
  }
}
window.customElements.define('return-order-inventory-popup', ReturnOrderInventoryPopup)
