import '@things-factory/grist-ui'

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

import { MultiColumnFormStyles } from '@things-factory/form-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { client, CustomAlert } from '@things-factory/shell'
import { ScrollbarStyles } from '@things-factory/styles'
import { isMobileDevice } from '@things-factory/utils'

import { fetchLocationSortingRule } from '../../../fetch-location-sorting-rule'
import {
  INVENTORY_STATUS,
  LOCATION_SORTING_RULE,
  ORDER_INVENTORY_STATUS,
  ORDER_TYPES,
  PICKING_STANDARD
} from '../../constants'

export class ReleaseExtraProductPopup extends localize(i18next)(LitElement) {
  static get styles() {
    return [
      MultiColumnFormStyles,
      ScrollbarStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: hidden;
          background-color: white;
        }
        .picking-std-container {
          margin-top: 0px;
        }
        .container {
          flex: 1;
          display: flex;
          overflow-y: auto;
          min-height: 50vh;
          margin: 10;
        }
        .grist {
          display: flex;
          flex-direction: column;
          flex: 1;
          overflow-y: auto;
          padding: 5px;
        }
        .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);
        }
        .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);
        }
      `
    ]
  }

  static get properties() {
    return {
      releaseGoodNo: String,
      recall: Boolean,
      bizplace: Object,
      config: Object,

      _selectedInventories: Array,
      _pickingStd: String,
      inventoryGristConfig: Object,
      existingInventoryData: Object,
      inventoryData: Object
    }
  }

  render() {
    return html`
      <div class="container">
        <div class="grist">
          <h2>
            <mwc-icon>list_alt</mwc-icon>${i18next.t('title.existing_release_product_list')}${` [${i18next.t(
              PICKING_STANDARD[this._pickingStd].name
            )}]`}
          </h2>
          <data-grist
            id="existing-inventory-grist"
            .mode="${isMobileDevice() ? 'LIST' : 'GRID'}"
            .config="${this.existingInventoryGristConfig}"
            .data="${this.existingInventoryData}"
            @record-change="${this._onProductChangeHandler.bind(this, 'existing')}"
            @field-change="${this._onExistingInventoryFieldChanged.bind(this)}"
          ></data-grist>
        </div>

        <div class="grist">
          <h2>
            <mwc-icon>list_alt</mwc-icon>${i18next.t('title.new_release_product_list')}${` [${i18next.t(
              PICKING_STANDARD[this._pickingStd].name
            )}]`}
          </h2>
          <data-grist
            id="inventory-grist"
            .mode="${isMobileDevice() ? 'LIST' : 'GRID'}"
            .config="${this.inventoryGristConfig}"
            .data="${this.inventoryData}"
            @record-change="${this._onProductChangeHandler.bind(this, 'new')}"
            @field-change="${this._onInventoryFieldChanged.bind(this)}"
          ></data-grist>
        </div>
      </div>

      <div class="button-container">
        <mwc-button
          raised
          danger
          @click="${() => {
            history.back()
          }}"
        >
          ${i18next.t('button.cancel')}
        </mwc-button>
        <mwc-button raised @click="${this._addExtraProducts.bind(this)}">${i18next.t('button.add_edit')}</mwc-button>
      </div>
    `
  }

  constructor() {
    super()
    this.initProperties()
    this._pickingStd = PICKING_STANDARD.SELECT_BY_PALLET.value
  }

  initProperties() {
    this.existingInventoryData = {
      ...this.existingInventoryData,
      records: this.existingInventoryData ? this.existingInventoryData : []
    }
    this.inventoryData = { ...this.inventoryData, records: [] }
  }

  async updated(changeProps) {
    if (changeProps.has('_pickingStd')) {
      await this.switchPickingType()
    }
  }

  get existingInventoryGrist() {
    return this.shadowRoot.querySelector('data-grist#existing-inventory-grist')
  }

  get inventoryGrist() {
    return this.shadowRoot.querySelector('data-grist#inventory-grist')
  }

  async switchPickingType() {
    this.resetPage()
    const locationSortingRules = await fetchLocationSortingRule(LOCATION_SORTING_RULE.CREATE_RELEASE_ORDER.value)

    this.existingInventoryGristConfig = {
      pagination: { infinite: true },
      rows: {
        appendable: false,
        selectable: { multiple: true },
        classifier: (record, rowIndex) => {
          return {
            emphasized: record.status === ORDER_INVENTORY_STATUS.PICKED.value
          }
        }
      },
      list: { fields: ['inventory', 'product', 'location', 'releaseQty'] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'object',
          name: 'inventory',
          header: i18next.t('field.inventory_list'),
          record: {
            options: {
              queryName: 'inventoriesByPallet',
              basicArgs: {
                filters: [
                  { name: 'status', operator: 'eq', value: INVENTORY_STATUS.STORED.value },
                  { name: 'bizplace', value: [this.bizplace], operator: 'in' }
                ],
                locationSortingRules
              },
              nameField: 'batchId',
              descriptionField: 'palletId',
              select: [
                { name: 'id', hidden: true },
                { name: 'name', hidden: true },
                { name: 'palletId', header: i18next.t('field.lot_id') },
                { name: 'cartonId', header: i18next.t('field.carton_id') },
                { name: 'product', type: 'object', queryName: 'products' },
                { name: 'batchId', header: i18next.t('field.batch_id') },
                {
                  name: 'location',
                  type: 'object',
                  queryName: 'locations',
                  field: 'name'
                },
                { name: 'packingType', header: i18next.t('field.packing_type') },
                { name: 'remainQty', type: 'float' },
                {
                  name: 'remainUomValue',
                  type: 'float',
                  header: i18next.t('field.total_uom_value')
                },
                { name: 'batchIdRef', header: i18next.t('field.batch_no_ref') }
              ],
              list: {
                fields: ['palletId', 'cartonId', 'product', 'batchId', 'location', 'remainUomValue', 'batchIdRef']
              }
            }
          },
          width: 250
        },
        {
          type: 'object',
          name: 'product',
          header: i18next.t('field.product'),
          width: 150
        },
        {
          type: 'object',
          name: 'location',
          header: i18next.t('field.location'),
          width: 150
        },
        {
          type: 'code',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          record: {
            codeName: 'PACKING_TYPES'
          },
          width: 150
        },
        {
          type: 'string',
          name: 'status',
          header: i18next.t('field.status'),
          width: 100
        },
        {
          type: 'float',
          name: 'addableQty',
          header: i18next.t('field.addable_qty'),
          width: 100
        },
        {
          type: 'float',
          name: 'releaseQty',
          header: i18next.t('field.release_qty'),
          record: { editable: true, options: { min: 0 } },
          width: 100
        },
        {
          type: 'float',
          name: 'addableUomValue',
          header: i18next.t('field.addable_uom_value'),
          width: 100
        },
        {
          type: 'float',
          name: 'releaseUomValue',
          header: i18next.t('field.release_uom_value'),
          record: { editable: true, options: { min: 0 } },
          width: 100
        }
      ]
    }

    this.inventoryGristConfig = {
      pagination: { infinite: true },
      rows: {
        selectable: { multiple: true }
      },
      list: { fields: ['inventory', 'product', 'location', 'releaseQty'] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'gutter',
          gutterName: 'button',
          icon: 'close',
          handlers: {
            click: (columns, data, column, record, rowIndex) => {
              try {
                const newData = data.records.filter((_, idx) => idx !== rowIndex)
                this.inventoryData = { ...this.inventoryData, records: newData }
                this.inventoryGrist.dirtyData.records = newData
                this._updateInventoryList()
              } catch (e) {
                this._showToast(e)
              }
            }
          }
        },
        {
          type: 'object',
          name: 'inventory',
          header: i18next.t('field.inventory_list'),
          record: {
            editable: true,
            align: 'left',
            options: {
              queryName: 'inventoriesByPallet',
              basicArgs: {
                filters: [
                  { name: 'status', operator: 'eq', value: INVENTORY_STATUS.STORED.value },
                  { name: 'bizplace_id', value: this.bizplace, operator: 'eq' },
                  { name: 'recall', value: this.recall ? this.recall : false, operator: '' },
                  {
                    name: 'invFilter',
                    value: this.existingInventoryGrist.dirtyData.records.map(itm => itm.inventory.id),
                    operator: 'eq'
                  }
                ],
                locationSortingRules
              },
              nameField: 'batchId',
              descriptionField: 'palletId',
              select: [
                { name: 'id', hidden: true },
                { name: 'name', hidden: true },
                { name: 'palletId', header: i18next.t('field.lot_id') },
                { name: 'cartonId', header: i18next.t('field.carton_id') },
                { name: 'product', type: 'object', queryName: 'products' },
                { name: 'productDetail', type: 'object', queryName: 'products', hidden: true },
                { name: 'batchId', header: i18next.t('field.batch_id') },
                {
                  name: 'location',
                  type: 'object',
                  queryName: 'locations',
                  field: 'name'
                },
                { name: 'packingType', header: i18next.t('field.packing_type') },
                { name: 'remainQty', header: i18next.t('field.remain_qty'), type: 'float' },
                {
                  name: 'remainUomValue',
                  type: 'float',
                  header: i18next.t('field.total_uom_value')
                },
                { name: 'batchIdRef', header: i18next.t('field.batch_no_ref') }
              ],
              list: { fields: ['palletId', 'cartonId', 'product', 'batchId', 'location', 'batchIdRef'] }
            }
          },
          width: 250
        },
        {
          type: 'object',
          name: 'product',
          header: i18next.t('field.product'),
          width: 150
        },
        {
          type: 'object',
          name: 'location',
          header: i18next.t('field.location'),
          width: 150
        },
        {
          type: 'code',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          record: {
            codeName: 'PACKING_TYPES'
          },
          width: 150
        },
        {
          type: 'float',
          name: 'remainQty',
          header: i18next.t('field.available_qty'),
          width: 100
        },
        {
          type: 'float',
          name: 'releaseQty',
          header: i18next.t('field.release_qty'),
          record: { editable: true, options: { min: 0 } },
          width: 100
        },
        {
          type: 'float',
          name: 'remainUomValue',
          header: i18next.t('field.available_uom_value'),
          width: 100
        },
        {
          type: 'float',
          name: 'releaseUomValue',
          header: i18next.t('field.release_uom_value'),
          record: { editable: true, options: { min: 0 } },
          width: 100
        }
      ]
    }
  }

  resetPage() {
    this._clearGristConditions()
  }

  _clearGristConditions() {
    if (this.inventoryGristConfig?.columns?.length) {
      this.inventoryGristConfig = {
        ...this.inventoryGristConfig,
        columns: this.inventoryGristConfig.columns.map(column => {
          if (column.name === 'inventory') {
            column.record.options.basicArgs = {
              filters: column.record.options.basicArgs.filters.filter(
                filter => filter.name !== 'batch_product' && filter.name !== 'id'
              )
            }
          }

          return column
        })
      }
    }
  }

  _updateInventoryList() {
    if (this._pickingStd === PICKING_STANDARD.SELECT_BY_PRODUCT.value) {
      const _selectedInv = (this.inventoryGrist.dirtyData.records || []).map(record => {
        return {
          batchId: record.inventory.batchId,
          packingType: record.inventory.packingType,
          productId: record.inventory.productId
        }
      })

      const config = {
        ...this.inventoryGristConfig,
        columns: this.inventoryGristConfig.columns.map(column => {
          if (column.name === 'inventory') {
            column.record.options.basicArgs = {
              ...column.record.options.basicArgs,
              filters: [...column.record.options.basicArgs.filters.filter(filter => filter.name !== 'batch_product')]
            }

            if (_selectedInv.length)
              column.record.options.basicArgs.filters = [
                ...column.record.options.basicArgs.filters,
                {
                  name: 'batch_product',
                  value: _selectedInv,
                  operator: 'notin'
                }
              ]
          }

          return column
        })
      }
      this.inventoryGristConfig = { ...this.inventoryGristConfig }
    } else {
      const _selectedInventories = (this.inventoryGrist.dirtyData.records || []).map(record => record.inventory.id)

      const config = {
        ...this.inventoryGristConfig,
        columns: this.inventoryGristConfig.columns.map(column => {
          if (column.name === 'inventory') {
            column.record.options.basicArgs = {
              ...column.record.options.basicArgs,
              filters: [...column.record.options.basicArgs.filters.filter(filter => filter.name !== 'id')]
            }

            if (_selectedInventories.length)
              column.record.options.basicArgs.filters = [
                ...column.record.options.basicArgs.filters,
                {
                  name: 'id',
                  value: _selectedInventories,
                  operator: 'notin'
                }
              ]
          }

          return column
        })
      }

      this.inventoryGristConfig = { ...config }
    }
  }

  _getStdDate() {
    let date = new Date()
    date.setDate(date.getDate())
    return date.toISOString().split('T')[0]
  }

  _onExistingInventoryFieldChanged(e) {
    let columnName = e.detail.column.name
    let packageUomValue = 0

    try {
      if (e.details?.after && e.details?.after !== 0) {
        throw new Error(i18next.t('text.invalid_form_value'))
      }

      const result = this._calculateQtyAndUom(
        packageUomValue,
        columnName,
        e.detail.record.uomValue,
        e.detail.record.qty,
        e.detail.record.__origin__.releaseUomValue,
        e.detail.record.__origin__.releaseQty,
        e.detail.record.__origin__.addableUomValue,
        e.detail.record.__origin__.addableQty,
        e.detail.record.__origin__.remainUomValue,
        e.detail.record.__origin__.remainQty,
        e.detail.after
      )

      this.existingInventoryData = {
        ...this.existingInventoryGrist.dirtyData,
        records: this.existingInventoryGrist.dirtyData.records.map((record, idx) => {
          if (result.releaseQty >= 0 && result.roundedUom >= 0) {
            if ((columnName == 'releaseUomValue' || columnName == 'releaseQty') && idx === e.detail.row) {
              if (columnName == 'releaseUomValue') {
                record.releaseQty = result.releaseQty
              }
              record.releaseUomValue = result.roundedUom
              record.addableQty = record.__origin__.releaseQty + record.__origin__.addableQty - result.releaseQty
              if (record.addableQty <= 0) {
                record.addableQty = 0
              }
              if (record.addableUomValue == 0) {
                record.addableUomValue =
                  record.addableQty * (record.__origin__.releaseUomValue / record.__origin__.releaseQty)
              } else {
                if (record.addableQty == 0) {
                  record.addableUomValue = 0
                } else {
                  if (e.detail.record.__origin__.releaseQty == 0 || e.detail.record.__origin__.releaseUomValue == 0) {
                    record.addableUomValue =
                      record.addableQty *
                      (e.detail.record.__origin__.addableUomValue / e.detail.record.__origin__.addableQty)
                  } else {
                    record.addableUomValue =
                      record.addableQty *
                      (e.detail.record.__origin__.releaseUomValue / e.detail.record.__origin__.releaseQty)
                  }
                }
              }
            }
          }

          let returnObj = {
            ...record
          }

          if (this._pickingStd === PICKING_STANDARD.SELECT_BY_PRODUCT.value) {
            returnObj.product = {
              id: record.inventory.productId,
              name: record.inventory.productName
            }
          }

          return returnObj
        })
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  _calculateQtyAndUom(
    packageUom,
    columnName,
    detailUom,
    detailQty,
    originUom,
    originQty,
    originAddableUom,
    originAddableQty,
    originRemainUom,
    originRemainQty,
    afterValue
  ) {
    var releaseQty = 0
    var roundedUom = 0

    if (afterValue >= 0) {
      if (columnName == 'releaseUomValue' || columnName == 'releaseQty') {
        if (originQty >= 0) {
          if (originQty == 0 || originUom == 0) {
            packageUom = originAddableUom / originAddableQty
          } else {
            packageUom = originUom / originQty
          }
        } else {
          packageUom = originRemainUom / originRemainQty
        }

        if (columnName === 'releaseQty') {
          if (afterValue - originQty <= originAddableQty) {
            releaseQty = afterValue || 0
          } else {
            releaseQty = originQty
          }
        } else if (columnName === 'releaseUomValue') {
          if (afterValue - originUom <= originAddableUom) {
            releaseQty = Math.round(afterValue / packageUom)
          } else {
            releaseQty = Math.round(originUom / packageUom)
          }
        }

        roundedUom = releaseQty * packageUom
        roundedUom = parseFloat(roundedUom.toFixed(3))
      }
    } else {
      releaseQty = afterValue
      roundedUom = afterValue
    }

    return { releaseQty, roundedUom }
  }

  _onInventoryFieldChanged(e) {
    let columnName = e.detail.column.name
    let roundedUomValue = e.detail.record.roundedUomValue || 0
    let releaseQty = 0
    let packageUomValue = 0

    try {
      if (Number.isNaN(e.detail.after)) {
        throw new Error(i18next.t('text.invalid_form_value'))
      }
    } catch (e) {
      this._showToast(e)
    }
    if (e.detail.after >= 0) {
      packageUomValue = e.detail.record.remainUomValue / e.detail.record.remainQty

      if (columnName === 'releaseQty' && e.detail.after <= e.detail.record.remainQty) {
        releaseQty = e.detail.after || 0
      } else {
        if (columnName === 'releaseUomValue' && e.detail.after <= e.detail.record.remainUomValue) {
          releaseQty = Math.round(e.detail.after / packageUomValue)
        }
      }
      roundedUomValue = releaseQty * packageUomValue
      roundedUomValue = parseFloat(roundedUomValue.toFixed(3))
    } else {
      releaseQty = e.detail.after
      roundedUomValue = e.detail.after
    }

    this.inventoryData = {
      ...this.inventoryGrist.dirtyData,
      records: this.inventoryGrist.dirtyData.records.map((record, idx) => {
        if (releaseQty >= 0 && roundedUomValue >= 0) {
          if ((columnName == 'releaseUomValue' || columnName == 'releaseQty') && idx === e.detail.row) {
            record.releaseQty = releaseQty
            record.releaseUomValue = roundedUomValue
          }
        }

        let returnObj = {
          ...record,
          ...record.inventory
        }

        if (this._pickingStd === PICKING_STANDARD.SELECT_BY_PRODUCT.value) {
          returnObj.product = {
            id: record.inventory.productId,
            name: record.inventory.productName
          }
        }

        return returnObj
      })
    }
  }

  _onProductChangeHandler(gristType, event) {
    const changeRecord = event.detail.after
    const beforeRecord = event.detail.before
    const changedColumn = event.detail.column.name
    var totalAvailableQty = 0
    var totalAvailableUomValue = 0

    try {
      if (Number.isNaN(changeRecord.releaseQty) || Number.isNaN(changeRecord.releaseUomValue)) {
        throw new Error(i18next.t('text.invalid_form_value'))
      }

      if (gristType == 'existing') {
        totalAvailableQty = beforeRecord.addableQty + beforeRecord.releaseQty
        totalAvailableUomValue = beforeRecord.addableUomValue + beforeRecord.releaseUomValue
      } else {
        totalAvailableQty = changeRecord.remainQty
        totalAvailableUomValue = changeRecord.remainUomValue
      }

      if (changedColumn === 'releaseQty') {
        this._validateReleaseQty(changeRecord.releaseQty, changeRecord.remainQty, totalAvailableQty)
      } else if (changedColumn === 'releaseUomValue') {
        this._validateReleaseUomValue(changeRecord.releaseUomValue, changeRecord.remainUomValue, totalAvailableUomValue)
      }
      this._updateInventoryList()
    } catch (e) {
      const beforeValue = event.detail.before && event.detail.before[event.detail.column.name]
      if (beforeValue) {
        event.detail.after[event.detail.column.name] = beforeValue
      } else {
        event.detail.after[event.detail.column.name] = 0
      }
      this._showToast(e)
    }
  }

  _validateReleaseQty(releaseQty, remainQty, totalAvailableQty) {
    if (remainQty === undefined) throw new Error(i18next.t('text.there_is_no_selected_items'))
    if (totalAvailableQty) {
      if (releaseQty < 0) {
        throw new Error(i18next.t('text.invalid_quantity_input'))
      } else if (releaseQty > totalAvailableQty) {
        throw new Error(i18next.t('text.available_quantity_insufficient'))
      }
    } else {
      if (releaseQty > remainQty) {
        throw new Error(i18next.t('text.available_quantity_insufficient'))
      }
    }
  }

  _validateReleaseUomValue(releaseUomValue, remainUomValue, totalAvailableUomValue) {
    if (remainUomValue === undefined) throw new Error(i18next.t('text.there_is_no_selected_items'))
    if (totalAvailableUomValue) {
      if (releaseUomValue < 0) {
        throw new Error(i18next.t('text.invalid_quantity_input'))
      } else if (releaseUomValue > totalAvailableUomValue) {
        throw new Error(i18next.t('text.available_uom_value_insufficient'))
      }
    } else {
      if (releaseUomValue > remainUomValue) {
        throw new Error(i18next.t('text.available_uom_value_insufficient'))
      }
    }
  }

  async _addExtraProducts() {
    try {
      this._validateProducts()
      const result = await CustomAlert({
        title: i18next.t('title.are_you_sure'),
        text: i18next.t('text.add_extra_product'),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (!result.value) return

      const releaseItem = this._getReleaseData()

      const response = await client.mutate({
        mutation: gql`
          mutation addReleaseGoodProducts(
            $name: String!
            $orderInventories: [NewOrderInventory]
            $existingOrderInventories: [NewOrderInventory]
          ) {
            addReleaseGoodProducts(
              name: $name
              orderInventories: $orderInventories
              existingOrderInventories: $existingOrderInventories
            )
          }
        `,
        variables: {
          name: this.releaseGoodNo,
          orderInventories: releaseItem.orderInventories,
          existingOrderInventories: releaseItem.existingOrderInventories
        }
      })

      if (!response.errors) {
        await CustomAlert({
          title: i18next.t('title.extra_products'),
          text: i18next.t('text.extra_products_were_added'),
          confirmButton: { text: i18next.t('button.confirm') }
        })

        this.dispatchEvent(new CustomEvent('completed'))
        history.back()
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  _getReleaseData() {
    let orderInventories = []
    if (this.inventoryGrist.dirtyData.records.length > 0) {
      orderInventories = this.inventoryGrist.dirtyData.records.map(record => {
        let newRecord = {
          releaseQty: record.releaseQty,
          releaseUomValue: record.releaseUomValue,
          batchId: record.inventory.batchId,
          batchIdRef: record.inventory.batchIdRef,
          packingType: record.inventory.packingType,
          type: ORDER_TYPES.RELEASE_OF_GOODS.value,
          status: ORDER_INVENTORY_STATUS.PENDING.value
        }

        if (record.isCrossDocking) newRecord.crossDocking = true

        if (this._pickingStd === PICKING_STANDARD.SELECT_BY_PRODUCT.value) {
          newRecord.product = { id: record.inventory.productId, name: record.inventory.productName }
        } else {
          newRecord.product = { id: record.inventory.product.id, name: record.inventory.product.name }
          newRecord.inventory = { id: record.id }
          newRecord.productDetail = { id: record.inventory.productDetail.id }
        }

        return newRecord
      })
    }

    let existingOrderInventories = []
    if (this.existingInventoryGrist.dirtyData.records.length > 0) {
      existingOrderInventories = this.existingInventoryGrist.dirtyData.records.map(record => {
        let existRecord = {
          releaseQty: record.releaseQty,
          releaseUomValue: record.releaseUomValue,
          batchId: record.inventory.batchId,
          batchIdRef: record.inventory.batchIdRef,
          packingType: record.inventory.packingType,
          type: ORDER_TYPES.RELEASE_OF_GOODS.value,
          status: ORDER_INVENTORY_STATUS.PENDING.value
        }

        if (record.isCrossDocking) existRecord.crossDocking = true

        if (this._pickingStd === PICKING_STANDARD.SELECT_BY_PRODUCT.value) {
          existRecord.product = { id: record.inventory.productId, name: record.inventory.productName }
        } else {
          existRecord.product = { id: record.inventory.product.id, name: record.inventory.product.name }
          existRecord.inventory = { id: record.id }
          existRecord.productDetail = { id: record.inventory.productDetail.id }
        }

        return existRecord
      })
    }

    return { orderInventories, existingOrderInventories }
  }

  _validateProducts() {
    // // no records
    // if (!this.inventoryGrist.dirtyData.records || !this.inventoryGrist.dirtyData.records.length)
    //   throw new Error(i18next.t('text.no_products'))
    // required field (batchId, packingType, uomValue, unit, packQty, palletQty)
    if (
      this.inventoryGrist.dirtyData.records.filter(
        record => !record.batchId || !record.packingType || !record.releaseUomValue || !record.releaseQty
      ).length
    )
      throw new Error(i18next.t('text.empty_value_in_list'))
  }

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

window.customElements.define('release-extra-product-popup', ReleaseExtraProductPopup)
