import '@things-factory/barcode-ui'
import '@things-factory/grist-ui'
import '../show-my-worksheet-list-popup'
import './picking-execution'

import gql from 'graphql-tag'
import { css, html, property } from 'lit-element'
import { sleep } from '@operato/utils'
import { MultiColumnFormStyles, SingleColumnFormStyles } from '@things-factory/form-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client, gqlContext, PageView, store } from '@things-factory/shell'
import { CommonButtonStyles } from '@things-factory/styles'
import { isMobileDevice } from '@things-factory/utils'
import { connect } from 'pwa-helpers/connect-mixin.js'

import { fetchLocationSortingRule } from '../../../fetch-location-sorting-rule'

import { showToast } from '../../../util'
import { BATCH_PICKING, LOCATION_SORTING_RULE, PICKING, WORKSHEET_STATUS } from '../../constants'

const PICKING_TYPES = { PICKING, BATCH_PICKING }

class PickingProductV2 extends connect(store)(localize(i18next)(PageView)) {
  static get properties() {
    return {
      _state: Object,
      _data: Object,
      _context: Object
    }
  }

  @property() _context = {
    title: i18next.t('title.picking'),
    help: 'operato-wms/outbound/picking-product-2'
  }

  static get styles() {
    return [
      MultiColumnFormStyles,
      SingleColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: hidden;
          padding: 0;
        }
        data-grist {
          overflow: auto;
          flex: 1;
        }
        h2 {
          padding: var(--subtitle-padding);
          font: var(--subtitle-font);
          color: var(--subtitle-text-color);
          border-bottom: var(--subtitle-border-bottom);
        }
        legend mwc-icon {
          vertical-align: middle;
          margin: var(--grist-title-icon-margin);
          font-size: var(--grist-title-icon-size);
          color: var(--grist-title-icon-color);
          cursor: pointer;
        }
        #worksheet-form {
          grid-column: span 12;
          padding: 0 10px;
        }

        @media screen and (max-width: 460px) {
          .single-column-form {
            max-width: 100%;
            grid-gap: 5px;
          }
        }
      `
    ]
  }

  configContext(
    actions = [
      {
        title: i18next.t('button.get_task'),
        action: this.getTask.bind(this),
        ...CommonButtonStyles.assignment
      },
      {
        title: i18next.t('button.my_worksheet'),
        action: showWorksheetList.bind(this),
        ...CommonButtonStyles.inspect
      }
    ]
  ) {
    this._context = {
      ...this._context,
      actions
    }

    this.updateContext()
  }

  get context() {
    return this._context
  }

  get worksheetNoInput() {
    return this.shadowRoot.querySelector('barcode-scanable-input[name=worksheetNo]')?.shadowRoot.querySelector('input')
  }

  constructor() {
    super()
    this.configContext()
  }

  render() {
    if (this._data) {
      return html`<picking-execution .parent=${this} .data=${this._data}></picking-execution>`
    } else {
      return html` <div class="${isMobileDevice() ? 'single-column-form' : 'multi-column-form'}">
        <form id="worksheet-form">
          <fieldset>
            <legend>${i18next.t('title.scan')}</legend>
            <label>${i18next.t('label.worksheet_no')}</label>
            <barcode-scanable-input
              name="worksheetNo"
              custom-input
              @keypress="${async e => {
                try {
                  if (e.keyCode === 13) {
                    e.preventDefault()
                    this._data = await fetchWorksheet(this.worksheetNoInput.value, this.context.locationSortingRules)
                    this.updateContext()
                  }
                } catch (e) {}
              }}"
            >
            </barcode-scanable-input>
          </fieldset>
        </form>
      </div>`
    }
  }

  async pageUpdated(changes, lifecycle) {
    if (this.active) {
    }
  }

  async pageInitialized() {
    this._context = {
      ...this._context,
      locationSortingRules: await fetchLocationSortingRule(LOCATION_SORTING_RULE.PICKING_PRODUCT.value)
    }
  }

  async getTask() {
    try {
      const response = await client.mutate({
        mutation: gql`
          mutation getZonePickingTask {
            getZonePickingTask {
              worksheet {
                id
                name
                type
                status
                startedAt
                bizplace {
                  name
                }
              }
              groupedOrderInventories {
                inventory {
                  id
                  palletId
                  cartonId
                  batchId
                  expirationDate
                  location {
                    name
                    description
                  }
                }
                product {
                  sku
                  name
                  description
                }
                releaseQty
                pickedQty
                status
                packingType
                packingSize
                conversion
              }
              inventoryChanges {
                id
                inventory {
                  id
                  product {
                    sku
                    name
                  }
                }
                palletId
                status
                transactionType
                details
              }
              releaseGood {
                id
                refNo2
              }
              completable
            }
          }
        `
      })

      if (!response.errors) {
        let data = response.data.getZonePickingTask
        this._data = mapWorksheetData(data)
      }
    } catch (e) {
      showToast('Something went wrong. Please contact support.')
    }
  }
}

window.customElements.define('picking-product-v2', PickingProductV2)

async function fetchWorksheet(worksheetNo, locationSortingRules) {
  if (!worksheetNo) return

  try {
    let response = await client.query({
      query: gql`
        query zonePickingWorksheet($name: String!, $locationSortingRules: [Sorting!], $filter: String) {
          zonePickingWorksheet(name: $name, locationSortingRules: $locationSortingRules, filter: $filter) {
            worksheet {
              id
              name
              type
              status
              startedAt
              bizplace {
                name
              }
            }
            groupedOrderInventories {
              inventory {
                id
                palletId
                cartonId
                batchId
                expirationDate
                location {
                  name
                  description
                }
              }
              product {
                sku
                name
                description
              }
              releaseQty
              pickedQty
              status
              packingType
              packingSize
              conversion
            }
            inventoryChanges {
              id
              inventory {
                id
                product {
                  sku
                  name
                }
              }
              palletId
              status
              transactionType
              details
            }
            releaseGood {
              id
              refNo2
            }
            completable
          }
        }
      `,
      variables: { name: worksheetNo, locationSortingRules: locationSortingRules, filter: 'PICKING' }
    })

    if (!response.errors) {
      let data = response.data.zonePickingWorksheet
      if (data.worksheet.status === WORKSHEET_STATUS.DONE.value) {
        return showToast({ type: 'failed', message: 'Worksheet is already done' })
      } else if (data.worksheet.status === WORKSHEET_STATUS.DEACTIVATED.value) {
        return showToast({ type: 'failed', message: 'Worksheet is not activated' })
      }
      return mapWorksheetData(data)
    }
  } catch (e) {
    throw new Error(e.message)
  }
}

function mapWorksheetData(data) {
  // Group unique refNo2 values
  const uniqueRefNo2s = [...new Set(data.releaseGood.map(rg => rg.refNo2).filter(refNo2 => refNo2))] // Filter out null/undefined values
  const groupedRefNo2 = uniqueRefNo2s.join(', ')

  const worksheetInfo = {
    id: data.worksheet.id,
    name: data.worksheet.name,
    type: data.worksheet.type,
    status: data.worksheet.status,
    bizplaceName: data.worksheet.bizplace.name,
    startedAt: data.worksheet.startedAt
      ? new Date(parseInt(data.worksheet.startedAt))
          .toLocaleString('en-CA', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            hour12: false
          })
          .replace(',', '')
      : null,
    groupedRefNo2
  }

  const worksheetDetailInfos = data.groupedOrderInventories.map(orderInv => ({
    inventoryId: orderInv.inventory.id,
    palletId: orderInv.inventory.palletId,
    cartonId: orderInv.inventory.cartonId,
    batchId: orderInv.inventory.batchId,
    product: {
      sku: orderInv.product.sku,
      name: orderInv.product.name,
      description: orderInv.product.description
    },
    qty: orderInv.pickedQty,
    releaseQty: orderInv.releaseQty,
    pickedQty: orderInv.pickedQty,
    expirationDate: orderInv.inventory.expirationDate
      ? new Date(orderInv.inventory.expirationDate).toISOString().slice(0, 10).replace('-', '/').replace('-', '/')
      : null,
    status: orderInv.status,
    packingType: orderInv.packingType,
    packingSize: orderInv.packingSize,
    conversion: orderInv.conversion,
    location: {
      name: orderInv.inventory.location.name,
      description: orderInv.inventory.location.description
    },
    relatedOrderInv: {
      id: orderInv.id,
      batchId: orderInv.inventory.batchId,
      packingType: orderInv.packingType,
      product: {
        sku: orderInv.product.sku,
        name: orderInv.product.name,
        description: orderInv.product.description
      }
    }
  }))

  const issues = data.inventoryChanges.map(ic => {
    return {
      ...ic,
      inventoryId: ic.inventory.id
    }
  })

  const completable = data.completable

  return {
    worksheetDetailInfos,
    issues,
    completable,
    worksheetInfo
  }
}

async function showWorksheetList() {
  await sleep(1010)
  openPopup(html` <show-my-worksheet-list-popup .type="ZONE_PICKING"></show-my-worksheet-list-popup> `, {
    backdrop: true,
    size: 'small',
    title: i18next.t('title.my_worksheet_list')
  })
}
