import { MultiColumnFormStyles } from '@things-factory/form-ui'
import '@things-factory/grist-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { client, CustomAlert, navigate, PageView, store } from '@things-factory/shell'
import { CommonButtonStyles } from '@things-factory/styles'
import { isMobileDevice } from '@things-factory/utils'
import gql from 'graphql-tag'
import { css, html } from 'lit-element'
import { connect } from 'pwa-helpers/connect-mixin'
import '../../components/attachment-viewer'
import '../../components/popup-note'
import '../../components/vas-templates'
import { ORDER_STATUS } from '../../constants'

//vas --inbound
class CheckReturnOrder extends connect(store)(localize(i18next)(PageView)) {
  static get properties() {
    return {
      _userType: String,
      _returnOrderNo: String,
      _template: Object,
      _ownTransport: Boolean,
      _crossDocking: Boolean,
      _ganNo: String,
      _exportOption: Boolean,
      customerBizplaceId: String,
      partnerBizplaceId: String,
      inventoryGristConfig: Object,
      inventoryData: Object,
      _attachments: Array,
      _status: String,
      _mimetype: String,
      _doPath: String
    }
  }

  static get styles() {
    return [
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow-x: auto;
        }
        .container {
          flex: 1;
          display: flex;
          overflow-y: auto;
        }
        .grist {
          background-color: var(--main-section-background-color);
          display: flex;
          flex-direction: column;
          flex: 1;
          overflow-y: auto;
        }
        .guide-container {
          max-width: 30vw;
          display: flex;
          flex-direction: column;
        }
        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 {
          margin: var(--grist-title-margin);
          border: var(--grist-title-border);
          font: var(--grist-title-font);
          color: var(--secondary-color);
        }

        .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);
        }

        h2 + data-grist {
          padding-top: var(--grist-title-with-grid-padding);
        }

        .ro-preview {
          display: flex;
          flex-direction: row;
          flex: 1;
        }
        attachment-viewer {
          flex: 1;
        }

        [options-wrap] *,
        [attachment-wrap] a * {
          vertical-align: middle;
        }
        [options-wrap] input[type='checkbox'] {
          left: 0;
        }
        [options-wrap] input[type='checkbox'] + label {
          margin-right: 20px;
          padding-left: 0;
        }
        [attachment-wrap] {
          grid-column: span 9 / auto;
        }
        [attachment-wrap] a {
          display: block;
          text-overflow: ellipsis;
          overflow: hidden;
          white-space: nowrap;
          color: var(--primary-color);
          font-size: var(--fontsize-default);
        }
        [attachment-wrap] {
          margin: 0;
          padding: 0;
          list-style: none;
        }
        [attachment-wrap] a mwc-icon {
          font-size: var(--fontsize-default);
        }
      `
    ]
  }

  render() {
    return html`
      <form name="returnOrder" class="multi-column-form">
        <fieldset>
          <legend>${i18next.t('title.return_order_no')}: ${this._returnOrderNo}</legend>

          <label>${i18next.t('label.options')}</label>
          <div options-wrap>
            <input id="ownTransport" type="checkbox" name="ownTransport" ?checked="${this._ownTransport}" disabled />
            <label>${i18next.t('label.own_transport')}</label>

            <input
              id="warehouseTransport"
              type="checkbox"
              name="warehouseTransport"
              ?checked="${!this._ownTransport}"
              disabled
            />
            <label>${i18next.t('label.warehouse_transport')}</label>
          </div>

          <label>${i18next.t('label.company')}</label>
          <input name="bizplaceName" value="${this._bizplaceName}" readonly />

          <label>${i18next.t('label.ref_no')}</label>
          <input name="refNo" readonly />

          <label>${i18next.t('label.eta_date')}</label>
          <input name="etaDate" type="date" readonly />

          ${this._attachments?.length > 0
            ? html`
                <label>${i18next.t('label.attachment')}</label>
                <ul attachment-wrap>
                  ${(this._attachments || []).map(
                    attachment =>
                      html`
                        <li>
                          <a href="${location.origin}/attachment/${attachment.path}" download
                            ><mwc-icon>attach_file</mwc-icon> ${attachment.name}</a
                          >
                        </li>
                      `
                  )}
                </ul>
              `
            : ''}
        </fieldset>
      </form>

      <div class="container">
        <div class="grist">
          <h2><mwc-icon>list_alt</mwc-icon>${i18next.t('title.return_product_list')}</h2>
          <data-grist
            id="inventory-grist"
            .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
            .config=${this.inventoryGristConfig}
            .data=${this.inventoryData}
          ></data-grist>
        </div>
      </div>
    `
  }

  constructor() {
    super()
    this._exportOption = false
    this._ownTransport = true
    this._downloadable = true
    this._attachments = []
    this.inventoryData = { records: [] }
  }

  get context() {
    return {
      title: i18next.t('title.check_return_order'),
      actions: [
        {
          title: i18next.t('button.arrived'),
          action: this._checkReturnOrder.bind(this),
          ...CommonButtonStyles.confirm
        },
        {
          title: i18next.t('button.back'),
          action: () => history.back(),
          ...CommonButtonStyles.back
        }
      ],
      help: 'operato-wms/return-order/check-return-order'
    }
  }

  get returnOrderForm() {
    return this.shadowRoot.querySelector('form[name=returnOrder]')
  }

  get _ownTransportInput() {
    return this.shadowRoot.querySelector('input[name=ownTransport]')
  }

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

  async pageUpdated(changes) {
    if (this.active) {
      if (changes.resourceId) {
        this._returnOrderNo = changes.resourceId
      }

      if (this._returnOrderNo) {
        await this._fetchReturnOrder(this._returnOrderNo)
      }
    }
  }

  pageInitialized() {
    this.inventoryGristConfig = {
      pagination: { infinite: true },
      rows: { selectable: { multiple: true }, appendable: false },
      list: { fields: ['sku', 'productName', 'batchId', 'packingType', 'packingSize', 'returnQty', 'returnUomValue'] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'string',
          name: 'batchId',
          header: i18next.t('field.batch_id'),
          width: 100
        },
        {
          type: 'string',
          name: 'sku',
          header: i18next.t('field.sku'),
          width: 150
        },
        {
          type: 'string',
          name: 'productName',
          header: i18next.t('field.product'),
          width: 150
        },
        {
          type: 'string',
          name: 'brand',
          header: i18next.t('field.brand'),
          width: 150
        },
        {
          type: 'string',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          width: 150
        },
        {
          type: 'float',
          name: 'packingSize',
          header: i18next.t('field.packing_size'),
          width: 150
        },
        {
          type: 'integer',
          name: 'returnQty',
          header: i18next.t('field.return_qty'),
          width: 100
        },
        {
          type: 'float',
          name: 'returnUomValue',
          header: i18next.t('field.return_uom_value'),
          width: 100
        },
        {
          type: 'string',
          name: 'remark',
          header: i18next.t('field.remark'),
          width: 300
        }
      ]
    }
  }

  async _fetchReturnOrder() {
    if (!this._returnOrderNo) return
    const response = await client.query({
      query: gql`
        query returnOrderDetail($name: String!) {
          returnOrderDetail(name: $name) {
            id
            name
            truckNo
            status
            refNo
            ownTransport
            eta
            etaDate
            attachment {
              id
              name
              refBy
              path
              mimetype
            }
            bizplace {
              id
              name
              description
            }
            inventoryInfos {
              id
              name
              batchId
              palletId
              product {
                id
                name
                description
                sku
                brand
              }
              productName
              packingType
              packingSize
              returnQty
              returnUomValue
              remark
              status
            }
          }
        }
      `,
      variables: {
        name: this._returnOrderNo
      }
    })

    if (!response.errors) {
      const returnOrder = response.data.returnOrderDetail
      const orderInventories = returnOrder.inventoryInfos

      this.partnerBizplaceId = returnOrder.bizplace.id
      this._ownTransport = returnOrder.ownTransport
      this._bizplaceName = returnOrder.bizplace.name
      this._status = returnOrder.status

      this._fillupROForm(returnOrder)

      if (returnOrder && returnOrder?.attachment) {
        this._attachments = returnOrder && returnOrder.attachment
      }

      this.inventoryData = {
        records: orderInventories.map(orderInventory => {
          return {
            ...orderInventory,
            sku: orderInventory.product.sku,
            brand: orderInventory.product.brand
          }
        })
      }
    }
  }

  get _isDownloadable() {
    return this._status !== ORDER_STATUS.PENDING.value
  }

  _fillupROForm(data) {
    this._fillupForm(this.returnOrderForm, data)
  }

  _fillupForm(form, data) {
    form.reset()
    for (let key in data) {
      Array.from(form.querySelectorAll('input')).forEach(field => {
        if (field.name === key && field.type === 'checkbox') {
          field.checked = data[key]
        } else if (field.name === key && field.type === 'datetime-local') {
          const datetime = Number(data[key])
          const timezoneOffset = new Date(datetime).getTimezoneOffset() * 60000
          field.value = new Date(datetime - timezoneOffset).toISOString().slice(0, -1)
        } else if (field.name === key) {
          if (data[key] instanceof Object) {
            const objectData = data[key]
            field.value = `${objectData.name} ${objectData.description ? `(${objectData.description})` : ''}`
          } else {
            field.value = data[key]
          }
        }
      })
    }
  }

  async _checkReturnOrder() {
    try {
      let result = await CustomAlert({
        title: i18next.t('title.are_you_sure'),
        text: i18next.t('text.check_to_arrived'),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (!result.value) return

      const response = await client.mutate({
        mutation: gql`
          mutation checkReturnOrder($name: String!) {
            checkReturnOrder(name: $name) {
              name
            }
          }
        `,
        variables: {
          name: this._returnOrderNo
        }
      })

      if (!response.errors) {
        navigate(`return_order_assign_buffer_location/${this._returnOrderNo}`)

        this._showToast({ message: i18next.t('text.return_order_is_arrived') })
      }
    } catch (e) {
      this._showToast(e)
    }
  }

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

window.customElements.define('check-return-order', CheckReturnOrder)
