import '@material/mwc-button/mwc-button'
import '@things-factory/grist-ui'
import './inventory-history-by-pallet'

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

import { CONDITION_OF_GOODS } from '../constants'
import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client } from '@things-factory/shell'
import { ScrollbarStyles } from '@things-factory/styles'
import { isMobileDevice } from '@things-factory/utils'

class InventoryByProductDetail extends localize(i18next)(LitElement) {
  static get styles() {
    return [
      ScrollbarStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: hidden;
        }

        search-form {
          overflow: visible;
        }

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

  static get properties() {
    return {
      _searchFields: Array,
      config: Object,
      data: Object,
      productId: String,
      bizplaceId: String
    }
  }

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

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

  firstUpdated() {
    this._searchFields = [
      {
        label: i18next.t('field.batch_id'),
        name: 'batchId',
        type: 'text',
        props: { searchOper: 'i_like' }
      },
      {
        label: i18next.t('field.lot_id'),
        name: 'palletId',
        type: 'text',
        props: { searchOper: 'i_like' }
      },
      {
        label: i18next.t('field.carton_id'),
        name: 'cartonId',
        type: 'text',
        props: { searchOper: 'i_like' }
      },
      {
        label: i18next.t('field.location'),
        name: 'location',
        type: 'object',
        queryName: 'locations',
        field: 'name'
      },
      // {
      //   label: i18next.t('field.expiring_in'),
      //   name: 'expiringIn',
      //   type: 'select',
      //   options: [
      //     { value: '' },
      //     { name: i18next.t('text.3_months'), value: '3 months' },
      //     { name: i18next.t('text.6_months'), value: '6 months' },
      //     { name: i18next.t('text.9_months'), value: '9 months' },
      //     { name: i18next.t('text.12_months'), value: '12 months' }
      //   ],
      //   props: { searchOper: 'eq' }
      // },
      {
        label: i18next.t('field.has_balance'),
        name: 'remainOnly',
        type: 'checkbox',
        value: true,
        props: { searchOper: 'eq' }
      }
    ]

    this.config = {
      list: { fields: ['palletId', 'batchId', 'orderRefNo', 'orderNo', 'zone', 'location', 'qty', 'batchIdRef'] },
      rows: { appendable: false },
      columns: [
        {
          type: 'gutter',
          gutterName: 'button',
          icon: 'reorder',
          handlers: {
            click: this._showInventoryMovement.bind(this)
          }
        },
        {
          type: 'string',
          name: 'batchId',
          header: i18next.t('field.batch_id'),
          width: 200
        },
        {
          type: 'string',
          name: 'palletId',
          header: i18next.t('field.lot_id'),
          width: 200
        },
        {
          type: 'string',
          name: 'cartonId',
          header: i18next.t('field.carton_id'),
          width: 200
        },
        {
          type: 'string',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          width: 200
        },
        {
          type: 'object',
          name: 'location',
          header: i18next.t('field.location'),
          sortable: true,
          width: 200
        },
        {
          type: 'string',
          name: 'conditionOfGoods',
          header: i18next.t('field.inventory_quality'),
          sortable: true,
          width: 120,
          record: {
            renderer: (value, column, record, rowIndex, field) => {
              const condition = Object.values(CONDITION_OF_GOODS).find(c => c.value === value)
              return condition ? i18next.t(`label.${condition.name}`) : value || ''
            }
          }
        },
        {
          type: 'number',
          name: 'lockedQty',
          header: i18next.t('field.release_qty'),
          sortable: true,
          width: 160
        },
        {
          type: 'number',
          name: 'qty',
          header: i18next.t('field.available_qty'),
          sortable: true,
          width: 80
        },
        {
          type: 'string',
          name: 'uomValue',
          header: i18next.t('field.available_uom_value'),
          sortable: true,
          width: 80
        },
        {
          type: 'string',
          name: 'batchIdRef',
          header: i18next.t('field.batch_no_ref'),
          width: 200
        },
        {
          type: 'date',
          name: 'expirationDate',
          header: i18next.t('field.expiry_date'),
          sortable: true,
          width: 200
        },
        {
          type: 'date',
          name: 'manufactureDate',
          header: i18next.t('field.manufacture_date'),
          sortable: true,
          width: 200
        }
      ]
    }
  }

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

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

  async fetchHandler({ page, limit, sorters = [] }) {
    try {
      if (!this.productId) return
      let filters = await this.searchForm.getQueryFilters()

      if (filters && filters.length > 2 && filters.find(filter => filter.name == 'remainOnly')) {
        // only supports 2 filters including remainOnly (because its a boolean)
        this._showToast({ type: 'warning', message: i18next.t('text.only_supports_search_of_single_field') })
        return
      } else if (!filters.find(filter => filter.name == 'remainOnly')) {
        // when popup init, it doesnt capture the value of this field
        // hence, we need to push a default value as follows
        filters.push({ name: 'remainOnly', operator: 'eq', value: true })
      }

      const response = await client.query({
        query: gql`
          query inventories($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
            inventories(filters: $filters, pagination: $pagination, sortings: $sortings) {
              items {
                batchId
                palletId
                cartonId
                packingType
                location {
                  name
                  description
                }
                conditionOfGoods
                uom
                lockedQty
                qty
                uomValue
                batchIdRef
                expirationDate
                manufactureDate
              }
              total
            }
          }
        `,
        variables: {
          filters: [
            ...filters,
            { name: 'product_id', operator: 'eq', value: this.productId },
            { name: 'status', operator: 'in', value: ['STORED', 'TERMINATED', 'MISSING'] },
            { name: 'bizplace', operator: 'eq', value: this.bizplaceId }
          ],
          pagination: { page, limit },
          sortings: sorters
        }
      })

      if (!response.errors) {
        return {
          total: response.data.inventories.total || 0,
          records:
            response.data.inventories.items.map(item => {
              return {
                ...item,
                remainingQty: item.remainQty,
                uomValue: `${item.uomValue} ${item.uom}`
              }
            }) || []
        }
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  _showInventoryMovement(columns, data, column, record, rowIndex) {
    openPopup(html` <inventory-history-by-pallet .palletId="${record.palletId}"></inventory-history-by-pallet> `, {
      backdrop: true,
      size: 'large',
      title: `${record.palletId} - History`
    })
  }

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

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