import '@things-factory/form-ui'
import '@things-factory/grist-ui'
import '../inventory/inventory-by-product-detail'

import gql from 'graphql-tag'
import { css, html } from 'lit-element'
import { connect } from 'pwa-helpers/connect-mixin'

import { getCodeByName } from '@things-factory/code-base'
import { i18next, localize } from '@things-factory/i18n-base'
import { client, gqlContext, PageView, store } from '@things-factory/shell'
import { flattenObject, isMobileDevice } from '@things-factory/utils'

function formatLocalDate(date = new Date()) {
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}

class OutboundOrderDetailsReport extends connect(store)(localize(i18next)(PageView)) {
  static get styles() {
    return css`
      :host {
        display: flex;
        flex-direction: column;
        width: 100%;
      }

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

      .summary {
        background-color: var(--main-section-background-color);
        display: flex;
        flex-direction: column;
        overflow-y: auto;
        align-items: flex-end;
        padding: var(--data-list-item-padding);
        display: grid;
        font-size: 14px;
        color: #394e64;
        grid-template-columns: repeat(2, 1fr);
        grid-auto-rows: minmax(24px, auto);
      }
    `
  }

  static get properties() {
    return {
      _searchFields: Object,
      _config: Object,
      _partners: Object,
      __orderStatus: Object,
      _gristData: Object,
      data: Object
    }
  }

  get context() {
    return {
      title: i18next.t('title.outbound_order_details_report'),
      exportable: {
        name: i18next.t('title.outbound_order_details_report'),
        data: this._exportableData.bind(this)
      },
      help: 'operato-wms/report/outbound-order-details-report'
    }
  }

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

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

  get _bizplaceSelector() {
    return this.searchForm.shadowRoot.querySelector('select[name=bizplace]')
  }

  get _fromDateInput() {
    return this.searchForm.shadowRoot.querySelector('input[name=fromDate]')
  }

  get _toDateInput() {
    return this.searchForm.shadowRoot.querySelector('input[name=toDate]')
  }

  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>
    `
  }

  get searchFields() {
    return [
      {
        label: i18next.t('field.company'),
        name: 'bizplace',
        type: 'select',
        options: [
          { value: '' },
          ...this._partners
            .map(partner => {
              return {
                name: `${partner.name} ${partner.description ? `(${partner.description})` : ''}`,
                value: partner.id
              }
            })
            .sort(this._compareValues('name', 'asc'))
        ],
        props: { searchOper: 'eq' }
      },
      {
        label: i18next.t('field.from_date'),
        name: 'fromDate',
        type: 'date',
        props: {
          searchOper: 'eq',
          max: formatLocalDate(new Date())
        },
        value: (() => {
          const date = new Date()
          date.setMonth(date.getMonth() - 1)
          return formatLocalDate(date)
        })(),
        handlers: { change: this._modifyDateRange.bind(this) }
      },
      {
        label: i18next.t('field.to_date'),
        name: 'toDate',
        type: 'date',
        props: {
          searchOper: 'eq',
          min: (() => {
            const date = new Date()
            date.setMonth(date.getMonth() - 1)
            return formatLocalDate(date)
          })(),
          max: (() => {
            const max = new Date()
            return formatLocalDate(max)
          })()
        },
        value: formatLocalDate(new Date())
        // handlers: { change: this._submit.bind(this) }
      },
      {
        label: i18next.t('field.product_info'),
        name: 'product',
        type: 'string',
        props: { searchOper: 'in' }
      },
      {
        label: i18next.t('field.ro_no'),
        name: 'roNo',
        type: 'text',
        props: { searchOper: 'custom' }
      },
      {
        label: i18next.t('field.do_no'),
        name: 'doNo',
        type: 'text',
        props: { searchOper: 'custom' }
      },
      {
        label: i18next.t('field.status'),
        name: 'status',
        type: 'select',
        options: [
          { name: 'all', value: '' },
          ...this._orderStatus.map(status => {
            return { name: i18next.t(`label.${status.description}`), value: status.name }
          })
        ],
        value: 'DONE',
        props: { searchOper: 'eq' }
      },
      {
        label: i18next.t('field.picking_bin'),
        name: 'binLocation',
        type: 'text',
        props: { searchOper: 'ilike' }
      },
      {
        label: i18next.t('field.priority_delivery'),
        name: 'priorityDelivery',
        type: 'checkbox',
        props: { searchOper: 'eq' },
        attrs: ['indeterminate']
      },
      {
        label: i18next.t('field.by_packing_complete'),
        name: 'byPackingComplete',
        type: 'checkbox',
        props: { searchOper: 'eq' }
      }
    ]
  }

  get reportConfig() {
    let columns = [
      { type: 'gutter', gutterName: 'sequence' },
      {
        type: 'string',
        name: 'bizplace|name',
        header: i18next.t('field.company'),
        width: 200
      },
      {
        type: 'boolean',
        name: 'priorityDelivery',
        header: i18next.t('field.priority_delivery'),
        record: { align: 'center' },
        width: 120
      },
      {
        type: 'string',
        name: 'roNo',
        header: i18next.t('field.ro_no'),
        width: 200
      },
      {
        type: 'string',
        name: 'roType',
        header: i18next.t('field.ro_type'),
        width: 150
      },
      {
        type: 'string',
        name: 'doNo',
        header: i18next.t('field.do_no'),
        width: 200
      },
      {
        type: 'string',
        name: 'doDeliveryDate',
        header: i18next.t('field.do_delivery_date'),
        width: 200
      },
      {
        type: 'string',
        name: 'deliveryAddress',
        header: i18next.t('field.delivery_address'),
        width: 300
      },
      {
        type: 'string',
        name: 'manifestNo',
        header: i18next.t('field.manifest_no'),
        width: 200
      },
      {
        type: 'string',
        name: 'refNo1',
        header: i18next.t('field.ref_no'),
        width: 150
      },
      {
        type: 'string',
        name: 'refNo2',
        header: i18next.t('field.ref_no_2'),
        width: 150
      },
      {
        type: 'string',
        name: 'refNo3',
        header: i18next.t('field.ref_no_3'),
        width: 150
      },
      {
        type: 'boolean',
        name: 'exportOption',
        header: i18next.t('field.export'),
        record: { align: 'center' },
        width: 100
      },
      {
        type: 'string',
        name: 'containerNo',
        header: i18next.t('field.container_no'),
        record: { align: 'center' },
        width: 120
      },
      {
        type: 'string',
        name: 'containerSize',
        header: i18next.t('field.container_size'),
        record: { align: 'center' },
        width: 120
      },
      {
        type: 'string',
        name: 'transportOption',
        header: i18next.t('field.transport_option'),
        record: { align: 'center' },
        width: 120
      },
      {
        type: 'string',
        name: 'vehicleNo',
        header: i18next.t('field.vehicle_no'),
        record: { align: 'center' },
        width: 120
      },
      {
        type: 'string',
        name: 'driverName',
        header: i18next.t('field.driver_name'),
        record: { align: 'center' },
        width: 120
      },
      {
        type: 'float',
        name: 'palletQty',
        header: i18next.t('field.pallet_qty'),
        width: 120
      },
      {
        type: 'string',
        name: 'status',
        header: i18next.t('field.status'),
        width: 120
      },
      {
        type: 'string',
        name: 'orderCreatedBy',
        header: i18next.t('field.order_created_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'orderCreatedAt',
        header: i18next.t('field.order_created_at'),
        width: 170
      },
      {
        type: 'string',
        name: 'acceptedBy',
        header: i18next.t('field.accepted_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'acceptedAt',
        header: i18next.t('field.accepted_at'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'pickingStart',
        header: i18next.t('field.picking_start'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'pickingComplete',
        header: i18next.t('field.picking_end'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'packingStart',
        header: i18next.t('field.packing_start'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'packingComplete',
        header: i18next.t('field.packing_end'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'sortingStart',
        header: i18next.t('field.sorting_start'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'sortingComplete',
        header: i18next.t('field.sorting_end'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'loadingStart',
        header: i18next.t('field.loading_start'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'loadingComplete',
        header: i18next.t('field.loading_end'),
        width: 170
      },
      {
        type: 'string',
        name: 'product|sku',
        header: i18next.t('field.sku'),
        width: 150
      },
      {
        type: 'string',
        name: 'product|name',
        header: i18next.t('field.product_name'),
        width: 200
      },
      {
        type: 'string',
        name: 'product|description',
        header: i18next.t('field.product_description'),
        width: 300
      },
      {
        type: 'string',
        name: 'product|type',
        header: i18next.t('field.product_type'),
        width: 150
      },
      {
        type: 'string',
        name: 'packType',
        header: i18next.t('field.packing_type'),
        width: 150
      },
      {
        type: 'number',
        name: 'packSize',
        header: i18next.t('field.packing_size'),
        width: 150
      },
      {
        type: 'float',
        name: 'qty',
        header: i18next.t('field.qty'),
        width: 120
      },
      {
        type: 'float',
        name: 'uomValue',
        header: i18next.t('field.uom_value'),
        width: 120
      },
      {
        type: 'string',
        name: 'uom',
        header: i18next.t('field.uom'),
        width: 100
      },
      {
        type: 'float',
        name: 'unitVolume',
        header: i18next.t('field.unit_volume'),
        width: 120
      },
      {
        type: 'float',
        name: 'totalVolume',
        header: i18next.t('field.total_volume'),
        width: 120
      },
      {
        type: 'float',
        name: 'unitNettWeight',
        header: i18next.t('field.unit_nett_weight'),
        width: 120
      },
      {
        type: 'float',
        name: 'totalUnitNettWeight',
        header: i18next.t('field.total_unit_nett_weight'),
        width: 120
      },
      {
        type: 'float',
        name: 'unitGrossWeight',
        header: i18next.t('field.unit_gross_weight'),
        width: 120
      },
      {
        type: 'float',
        name: 'totalUnitGrossWeight',
        header: i18next.t('field.total_unit_gross_weight'),
        width: 120
      },
      {
        type: 'string',
        name: 'weightUnit',
        header: i18next.t('field.weight_unit'),
        width: 100
      },
      {
        type: 'float',
        name: 'returnToLocationQty',
        header: i18next.t('field.return_qty'),
        width: 120
      },
      {
        type: 'float',
        name: 'returnToLocationUomValue',
        header: i18next.t('field.return_uom'),
        width: 120
      },
      {
        type: 'string',
        name: 'palletId',
        header: i18next.t('field.lot_id'),
        width: 150
      },
      {
        type: 'string',
        name: 'cartonId',
        header: i18next.t('field.carton_id'),
        width: 150
      },
      {
        type: 'string',
        name: 'batchId',
        header: i18next.t('field.batch_id'),
        width: 150
      },
      {
        type: 'string',
        name: 'batchIdRef',
        header: i18next.t('field.batch_id_ref'),
        width: 150
      },
      {
        type: 'datetime',
        name: 'expirationDate',
        header: i18next.t('field.exp_date'),
        width: 170
      },
      {
        type: 'date',
        name: 'manufactureDate',
        header: i18next.t('field.manufacture_date'),
        width: 120
      },
      {
        type: 'string',
        name: 'pickingLocation',
        header: i18next.t('field.picking_location'),
        width: 150
      },
      {
        type: 'string',
        name: 'pickedBy',
        header: i18next.t('field.picked_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'pickedAt',
        header: i18next.t('field.picked_at'),
        width: 170
      },
      {
        type: 'string',
        name: 'packedBy',
        header: i18next.t('field.packed_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'packedAt',
        header: i18next.t('field.packed_at'),
        width: 170
      },
      {
        type: 'string',
        name: 'checkedRemarkBy',
        header: i18next.t('field.remark_checked_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'checkedRemarkAt',
        header: i18next.t('field.remark_checked_at'),
        width: 170
      },
      {
        type: 'string',
        name: 'loadedBy',
        header: i18next.t('field.loaded_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'loadedAt',
        header: i18next.t('field.loaded_at'),
        width: 170
      },
      {
        type: 'string',
        name: 'binLocation',
        header: i18next.t('field.picking_bin'),
        width: 170
      },
      {
        type: 'string',
        name: 'manifestedBy',
        header: i18next.t('field.manifested_by'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'manifestedAt',
        header: i18next.t('field.manifested_at'),
        width: 170
      },
      {
        type: 'datetime',
        name: 'dispatchedAt',
        header: i18next.t('field.dispatched_at'),
        width: 170
      }
    ]
    let list = {
      fields: [
        'bizplace|name',
        'priorityDelivery',
        'roNo',
        'roType',
        'doNo',
        'doDeliveryDate',
        'deliveryAddress',
        'refNo1',
        'refNo2',
        'refNo3',
        'status',
        'exportOption',
        'containerNo',
        'containerSize',
        'palletQty',
        'orderCreatedBy',
        'orderCreatedAt',
        'pickingStart',
        'pickingComplete',
        'packingStart',
        'packingComplete',
        'loadingStart',
        'loadingComplete',
        'acceptedBy',
        'acceptedAt',
        'product|sku',
        'product|name',
        'product|description',
        'product|type',
        'packType',
        'packSize',
        'qty',
        'uomValue',
        'uom',
        'returnToLocationQty',
        'returnToLocationUomValue',
        'unitVolume',
        'totalVolume',
        'unitNettWeight',
        'totalUnitNettWeight',
        'unitGrossWeight',
        'totalUnitGrossWeight',
        'weightUnit',
        'palletId',
        'cartonId',
        'batchId',
        'batchIdRef',
        'expirationDate',
        'manufactureDate',
        'pickingLocation',
        'pickedAt',
        'pickedBy',
        'packedAt',
        'packedBy',
        'checkedRemarkBy',
        'checkedRemarkAt',
        'loadedAt',
        'loadedBy',
        'manifestedAt',
        'manifestedBy',
        'dispatchedAt'
      ]
    }

    return {
      columns: columns,
      list,
      pagination: { limit: 100, pages: [100, 200, 500, 1000] },
      rows: {
        selectable: false,
        insertable: false,
        appendable: false
      }
    }
  }

  async pageInitialized() {
    this._gristData = { total: 0, totalWithOpeningBalance: 0, records: [] }
    this._products = []

    const [_orderStatusReq, _partnersReq] = await Promise.allSettled([
      getCodeByName('RO_REQUESTS_STATUS'),
      this._fetchPartners()
    ])

    this._orderStatus = _orderStatusReq.status == 'fulfilled' ? _orderStatusReq.value : []
    this._partners = _partnersReq.status == 'fulfilled' ? _partnersReq.value : []

    this._searchFields = this.searchFields
    this._config = this.reportConfig
  }

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

  async fetchHandler({ page, limit, sorters = [] }) {
    try {
      this._validate()
      let filters = this.searchForm.queryFilters.map(filter => {
        switch (filter.name) {
          case 'fromDate':
            let fromDt = new Date(filter.value)
            fromDt.setHours(0)
            filter.value = fromDt.toISOString()
            break
          case 'toDate':
            let toDt = new Date(filter.value)
            toDt.setHours(23, 59, 59)
            filter.value = toDt.toISOString()
            break
          default:
            break
        }
        return filter
      })

      const pagination = { page, limit }
      const sortings = sorters

      const response = await client.query({
        query: gql`
          query outboundOrderDetailsReport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
            outboundOrderDetailsReport(filters: $filters, pagination: $pagination, sortings: $sortings) {
              items {
                bizplace {
                  name
                  description
                }
                doNo
                doDeliveryDate
                deliveryAddress
                manifestNo
                roNo
                roType
                status
                refNo1
                refNo2
                refNo3
                containerSize
                transportOption
                vehicleNo
                driverName
                acceptedBy
                acceptedAt
                orderCreatedBy
                orderCreatedAt
                pickingStart
                pickingComplete
                packingStart
                packingComplete
                sortingStart
                sortingComplete
                loadingStart
                loadingComplete
                orderLineItem
                product {
                  sku
                  name
                  description
                  type
                }
                packType
                packSize
                qty
                uomValue
                returnToLocationQty
                returnToLocationUomValue
                uom
                unitVolume
                totalVolume
                unitNettWeight
                totalUnitNettWeight
                unitGrossWeight
                totalUnitGrossWeight
                weightUnit
                palletId
                cartonId
                batchId
                batchIdRef
                expirationDate
                manufactureDate
                pickingLocation
                pickedAt
                pickedBy
                packedAt
                packedBy
                checkedRemarkAt
                checkedRemarkBy
                loadedAt
                loadedBy
                dispatchedAt
                exportOption
                containerNo
                palletQty
                manifestedAt
                manifestedBy
                binLocation
                dispatchedAt
                priorityDelivery
              }
              total
            }
          }
        `,
        variables: { filters, pagination, sortings },
        context: gqlContext()
      })

      const data = {
        total: response.data.outboundOrderDetailsReport.total,
        records:
          response.data.outboundOrderDetailsReport.items.map(itm => {
            itm = {
              ...itm
              // unitCost: parseFloat(itm.unitCost ? itm.unitCost : 0).toFixed(2)
            }
            return flattenObject({ ...itm, bizplace: { name: `${itm.bizplace.name} ${itm.bizplace.description}` } })
          }) || []
      }

      this._gristData = {
        ...data
      }

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

  async _fetchPartners() {
    const filters = []
    const response = await client.query({
      query: gql`
        query partnersBizplaces($filters: [Filter!]) {
          partnersBizplaces(filters: $filters) {
            items {
              id
              name
              description
            }
          }
        }
      `,
      variables: { filters }
    })

    if (!response.errors) {
      return response.data.partnersBizplaces.items
    }
  }
  _validate() {
    if (!this.searchForm.shadowRoot.querySelector('form').checkValidity())
      throw new Error(i18next.t('text.invalid_form_value'))
    if (!this._bizplaceSelector.value) throw new Error(i18next.t('text.no_company_selected'))
    if (!this._fromDateInput.value) throw new Error(i18next.t('text.from_date_is_empty'))
    if (!this._toDateInput.value) throw new Error(i18next.t('text.to_date_is_empty'))
  }

  _compareValues(key, order = 'asc') {
    return function innerSort(a, b) {
      if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
        return 0
      }

      const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key]
      const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key]

      let comparison = 0
      if (varA > varB) {
        comparison = 1
      } else if (varA < varB) {
        comparison = -1
      }
      return order === 'desc' ? comparison * -1 : comparison
    }
  }

  _modifyDateRange(e) {
    const fromDate = e.currentTarget.value

    const minDate = new Date(fromDate)
    if (Number.isNaN(minDate.getTime())) return

    const maxDate = new Date(minDate)
    maxDate.setMonth(maxDate.getMonth() + 2)

    const min = formatLocalDate(minDate)
    const max = formatLocalDate(maxDate)

    if (this._toDateInput.value < fromDate) this._toDateInput.value = fromDate
    if (this._toDateInput.value > max) this._toDateInput.value = max

    this._toDateInput.max = max
    this._toDateInput.min = min
    this._submit()
  }

  _submit(e) {
    this._config = { ...this.reportConfig }
    this.searchForm.submit()
  }

  async _exportableData() {
    try {
      var headerSetting = [
        { header: i18next.t('field.company'), key: 'bizplace|name', width: 60, type: 'string' },
        { header: i18next.t('field.priority_delivery'), key: 'priorityDelivery', width: 20, type: 'string' },
        { header: i18next.t('field.ro_no'), key: 'roNo', width: 30, type: 'string' },
        { header: i18next.t('field.ro_type'), key: 'roType', width: 20, type: 'string' },
        { header: i18next.t('field.do_no'), key: 'doNo', width: 30, type: 'string' },
        { header: i18next.t('field.do_delivery_date'), key: 'doDeliveryDate', width: 30, type: 'string' },
        { header: i18next.t('field.delivery_address'), key: 'deliveryAddress', width: 40, type: 'string' },
        { header: i18next.t('field.manifest_no'), key: 'manifestNo', width: 30, type: 'string' },
        { header: i18next.t('field.ref_no'), key: 'refNo1', width: 60, type: 'string' },
        { header: i18next.t('field.ref_no_2'), key: 'refNo2', width: 60, type: 'string' },
        { header: i18next.t('field.ref_no_3'), key: 'refNo3', width: 60, type: 'string' },
        { header: i18next.t('field.export'), key: 'exportOption', width: 20, type: 'string' },
        { header: i18next.t('field.container_no'), key: 'containerNo', width: 30, type: 'string' },
        { header: i18next.t('field.container_size'), key: 'containerSize', width: 30, type: 'string' },
        { header: i18next.t('field.transport_option'), key: 'transportOption', width: 30, type: 'string' },
        { header: i18next.t('field.vehicle_no'), key: 'vehicleNo', width: 30, type: 'string' },
        { header: i18next.t('field.driver_name'), key: 'driverName', width: 30, type: 'string' },
        { header: i18next.t('field.pallet_qty'), key: 'palletQty', width: 30, type: 'string' },
        { header: i18next.t('field.status'), key: 'status', width: 30, type: 'string' },
        { header: i18next.t('field.order_created_by'), key: 'orderCreatedBy', width: 30, type: 'string' },
        { header: i18next.t('field.order_created_at'), key: 'orderCreatedAt', width: 30, type: 'string' },
        { header: i18next.t('field.accepted_by'), key: 'acceptedBy', width: 30, type: 'string' },
        { header: i18next.t('field.accepted_at'), key: 'acceptedAt', width: 30, type: 'string' },
        { header: i18next.t('field.picking_start'), key: 'pickingStart', width: 30, type: 'string' },
        { header: i18next.t('field.picking_end'), key: 'pickingComplete', width: 30, type: 'string' },
        { header: i18next.t('field.packing_start'), key: 'packingStart', width: 30, type: 'string' },
        { header: i18next.t('field.packing_end'), key: 'packingComplete', width: 30, type: 'string' },
        { header: i18next.t('field.sorting_start'), key: 'sortingStart', width: 30, type: 'string' },
        { header: i18next.t('field.sorting_end'), key: 'sortingComplete', width: 30, type: 'string' },
        { header: i18next.t('field.loading_start'), key: 'loadingStart', width: 30, type: 'string' },
        { header: i18next.t('field.loading_end'), key: 'loadingComplete', width: 30, type: 'string' },
        { header: i18next.t('field.sku'), key: 'product|sku', width: 25, type: 'string' },
        { header: i18next.t('field.product_name'), key: 'product|name', width: 50, type: 'string' },
        { header: i18next.t('field.product_description'), key: 'product|description', width: 50, type: 'string' },
        { header: i18next.t('field.product_type'), key: 'product|type', width: 30, type: 'string' },
        { header: i18next.t('field.picking_location'), key: 'pickingLocation', width: 30, type: 'string' },
        { header: i18next.t('field.packing_type'), key: 'packType', width: 25, type: 'string' },
        { header: i18next.t('field.packing_size'), key: 'packSize', width: 25, type: 'string' },
        { header: i18next.t('field.qty'), key: 'qty', width: 15, type: 'string' },
        { header: i18next.t('field.uom_value'), key: 'uomValue', width: 15, type: 'string' },
        { header: i18next.t('field.uom'), key: 'uom', width: 15, type: 'string' },
        { header: i18next.t('field.unit_volume'), key: 'unitVolume', width: 15, type: 'string' },
        { header: i18next.t('field.total_volume'), key: 'totalVolume', width: 15, type: 'string' },
        { header: i18next.t('field.unit_nett_weight'), key: 'unitNettWeight', width: 15, type: 'string' },
        { header: i18next.t('field.total_unit_nett_weight'), key: 'totalUnitNettWeight', width: 15, type: 'string' },
        { header: i18next.t('field.unit_gross_weight'), key: 'unitGrossWeight', width: 15, type: 'string' },
        { header: i18next.t('field.total_unit_gross_weight'), key: 'totalUnitGrossWeight', width: 15, type: 'string' },
        { header: i18next.t('field.weight_unit'), key: 'weightUnit', width: 15, type: 'string' },
        { header: i18next.t('field.return_qty'), key: 'returnToLocationQty', width: 15, type: 'string' },
        { header: i18next.t('field.return_uom'), key: 'returnToLocationUomValue', width: 15, type: 'string' },
        { header: i18next.t('field.lot_id'), key: 'palletId', width: 25, type: 'string' },
        { header: i18next.t('field.carton_id'), key: 'cartonId', width: 25, type: 'string' },
        { header: i18next.t('field.batch_id'), key: 'batchId', width: 25, type: 'string' },
        { header: i18next.t('field.batch_id_ref'), key: 'batchIdRef', width: 25, type: 'string' },
        { header: i18next.t('field.exp_date'), key: 'expirationDate', width: 15, type: 'string' },
        { header: i18next.t('field.manufacture_date'), key: 'manufactureDate', width: 15, type: 'string' },
        { header: i18next.t('field.picked_by'), key: 'pickedBy', width: 15, type: 'string' },
        { header: i18next.t('field.picked_at'), key: 'pickedAt', width: 15, type: 'string' },
        { header: i18next.t('field.packed_by'), key: 'packedBy', width: 15, type: 'string' },
        { header: i18next.t('field.packed_at'), key: 'packedAt', width: 15, type: 'string' },
        { header: i18next.t('field.remark_checked_by'), key: 'checkedRemarkBy', width: 15, type: 'string' },
        { header: i18next.t('field.remark_checked_at'), key: 'checkedRemarkAt', width: 15, type: 'string' },
        { header: i18next.t('field.loaded_by'), key: 'loadedBy', width: 15, type: 'string' },
        { header: i18next.t('field.loaded_at'), key: 'loadedAt', width: 15, type: 'string' },
        { header: i18next.t('field.picking_bin'), key: 'binLocation', width: 15, type: 'string' },
        { header: i18next.t('field.manifested_by'), key: 'manifestedBy', width: 15, type: 'string' },
        { header: i18next.t('field.manifested_at'), key: 'manifestedAt', width: 15, type: 'string' },
        { header: i18next.t('field.dispatched_at'), key: 'dispatchedAt', width: 15, type: 'string' }
      ]

      var exportData = {
        header: [...headerSetting],
        data: (await this.fetchHandler({ page: 1, limit: 9999999 })).records.map(itm => {
          return {
            ...itm,
            orderCreatedAt: itm.orderCreatedAt ? new Date(parseInt(itm.orderCreatedAt)).toLocaleString() : '',
            pickingStart: itm.pickingStart ? new Date(parseInt(itm.pickingStart)).toLocaleString() : '',
            pickingComplete: itm.pickingComplete ? new Date(parseInt(itm.pickingComplete)).toLocaleString() : '',
            packingStart: itm.packingStart ? new Date(parseInt(itm.packingStart)).toLocaleString() : '',
            packingComplete: itm.packingComplete ? new Date(parseInt(itm.packingComplete)).toLocaleString() : '',
            sortingStart: itm.sortingStart ? new Date(parseInt(itm.sortingStart)).toLocaleString() : '',
            sortingComplete: itm.sortingComplete ? new Date(parseInt(itm.sortingComplete)).toLocaleString() : '',
            loadingStart: itm.loadingStart ? new Date(parseInt(itm.loadingStart)).toLocaleString() : '',
            loadingComplete: itm.loadingComplete ? new Date(parseInt(itm.loadingComplete)).toLocaleString() : '',
            acceptedAt: itm.acceptedAt ? new Date(parseInt(itm.acceptedAt)).toLocaleString() : '',
            pickedAt: itm.pickedAt ? new Date(parseInt(itm.pickedAt)).toLocaleString() : '',
            packedAt: itm.packedAt ? new Date(parseInt(itm.packedAt)).toLocaleString() : '',
            loadedAt: itm.loadedAt ? new Date(parseInt(itm.loadedAt)).toLocaleString() : '',
            manifestedAt: itm.manifestedAt ? new Date(parseInt(itm.manifestedAt)).toLocaleString() : '',
            dispatchedAt: itm.dispatchedAt ? new Date(parseInt(itm.dispatchedAt)).toLocaleString() : '',
            expirationDate: itm.expirationDate ? new Date(parseInt(itm.expirationDate)).toLocaleString() : '',
            manufactureDate: itm.manufactureDate ? new Date(parseInt(itm.manufactureDate)).toLocaleString() : '',
            checkedRemarkAt: itm.checkedRemarkAt ? new Date(parseInt(itm.checkedRemarkAt)).toLocaleString() : ''
          }
        })
      }

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

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

window.customElements.define('outbound-order-details-report', OutboundOrderDetailsReport)
