import '@things-factory/barcode-ui'
import { MultiColumnFormStyles } from '@things-factory/form-ui'
import '@things-factory/grist-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client, CustomAlert, navigate, PageView } 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 { fetchSettingRule } from '../../fetch-setting-value'
import { WORKSHEET_STATUS } from '../constants'
import './carton-label-popup'
import './pallet-label-popup'
import './putaway/putaway-worksheet-generate-popup'

class WorksheetUnloadingReturn extends localize(i18next)(PageView) {
  static get properties() {
    return {
      _worksheetNo: String,
      _worksheetStatus: String,
      _statusList: Array,
      _returnOrderNo: String,
      _enableCartonLabel: Boolean,
      config: Object,
      data: Object
    }
  }

  static get styles() {
    return [
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow-x: auto;
        }
        .form-container {
          display: flex;
        }
        .form-container > form {
          flex: 1;
        }
        barcode-tag {
          width: 100px;
          height: 100px;
          margin: 10px;
        }
        .grist {
          background-color: var(--main-section-background-color);
          display: flex;
          flex-direction: column;
          flex: 1;
          overflow-y: auto;
        }
        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);
        }
      `
    ]
  }

  get context() {
    var actions = [
      {
        title: i18next.t('button.back'),
        action: () => navigate('external_return_worksheets'),
        ...CommonButtonStyles.back
      }
    ]

    if (this._worksheetStatus === WORKSHEET_STATUS.DEACTIVATED.value) {
      actions.push({
        title: i18next.t('button.activate'),
        action: this._activateWorksheet.bind(this),
        ...CommonButtonStyles.activate
      })
      this._actions = [
        {
          title: i18next.t('button.activate'),
          action: this._activateWorksheet.bind(this),
          ...CommonButtonStyles.activate
        }
      ]
    }

    if (this._worksheetStatus === WORKSHEET_STATUS.EXECUTING.value) {
      if (this._enableCartonLabel) {
        actions.push({
          title: i18next.t('button.carton_label_print'),
          action: this._openCartonLabelPrintPopup.bind(this),
          ...CommonButtonStyles.label
        })
      } else {
        actions.push({
          title: i18next.t('button.lot_label_print'),
          action: this._openLotLabelPrintPopup.bind(this),
          ...CommonButtonStyles.label
        })
      }

      if (this.data?.records?.some(wsd => wsd.status === WORKSHEET_STATUS.PARTIALLY_UNLOADED.value)) {
        actions.push({
          title: i18next.t('button.create_putaway_worksheet'),
          action: this._showPutawayWorksheetPopup.bind(this),
          ...CommonButtonStyles.add
        })
      }
    }

    return {
      title: i18next.t('title.worksheet_unloading_return'),
      actions,
      printable: {
        accept: ['preview'],
        content: this
      },
      help: 'operato-wms/inbound/worksheet-unloading-return'
    }
  }

  constructor() {
    super()
    this._statusList = Object.keys(WORKSHEET_STATUS).map(key => {
      return { value: WORKSHEET_STATUS[key].value, display: WORKSHEET_STATUS[key].name }
    })
  }

  render() {
    return html`
      <div class="form-container">
        <form class="multi-column-form">
          <fieldset>
            <legend>${i18next.t('title.customer_return')}</legend>
            <label>${i18next.t('label.return_order_no')}</label>
            <input name="returnOrder" readonly />

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

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

            <label>${i18next.t('label.status')}</label>
            <input
              name="status"
              value="${this._statusList.find(x => x.value == this._worksheetStatus)?.display || ''}"
              readonly
              disabled
            />
          </fieldset>
        </form>

        <barcode-tag bcid="qrcode" .value=${this._returnOrderNo} showLogo="true"></barcode-tag>
      </div>

      <div class="grist">
        <h2><mwc-icon>list_alt</mwc-icon>${i18next.t('title.product')}</h2>

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

  async pageUpdated(changes) {
    if (this.active) {
      if (changes.resourceId) {
        this._worksheetNo = changes.resourceId
      }
      if (this._worksheetNo) {
        await this.fetchWorksheet()
        this.updateContext()
        this._updateGristConfig()
      } else {
        //clear the page
        this.form.reset()
      }
    }
  }

  pageInitialized() {
    this.preConfig = {
      rows: { appendable: false },
      list: { fields: ['batchId', 'palletId', 'product'] },
      pagination: { infinite: true },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'string',
          name: 'batchId',
          header: i18next.t('field.batch_id'),
          width: 150
        },
        {
          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: 'object',
          name: 'product',
          header: i18next.t('field.product'),
          width: 350
        },
        {
          type: 'string',
          name: 'brand',
          header: i18next.t('field.brand'),
          width: 150
        },
        {
          type: 'string',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          width: 100
        },
        {
          type: 'float',
          name: 'packingSize',
          header: i18next.t('field.packing_size'),
          width: 100
        },
        {
          type: 'float',
          name: 'returnQty',
          header: i18next.t('field.return_qty'),
          width: 80
        },
        {
          type: 'string',
          name: 'remark',
          header: i18next.t('field.remark'),
          width: 300
        }
      ]
    }
  }

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

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

  async fetchWorksheet() {
    if (!this._worksheetNo) return
    const response = await client.query({
      query: gql`
        query ($name: String!) {
          worksheet(name: $name) {
            status
            releaseGood {
              name
              description
              refNo
            }
            returnOrder {
              id
              name
              description
              refNo
            }
            bizplace {
              name
              description
              domain {
                id
              }
            }
            worksheetDetails {
              id
              name
              description
              targetInventory {
                inventory {
                  batchId
                  palletId
                  cartonId
                  product {
                    name
                    brand
                    description
                  }
                  packingType
                  packingSize
                  location {
                    name
                    description
                  }
                  qty
                }
                remark
                returnQty
              }
              status
              issue
            }
          }
        }
      `,
      variables: { name: this._worksheetNo }
    })

    if (!response.errors) {
      const worksheet = response.data.worksheet
      const worksheetDetails = worksheet.worksheetDetails
      const partnerDomainId = worksheet.bizplace.domain.id

      this._worksheetStatus = worksheet.status
      this._returnOrder = worksheet && worksheet.returnOrder
      this._returnOrderNo = (worksheet.returnOrder && worksheet.returnOrder.name) || ''
      this._fillupForm({
        ...worksheet,
        returnOrder: worksheet.returnOrder.name,
        bizplace: worksheet.bizplace.name,
        refNo: worksheet.returnOrder.refNo
      })
      this.data = {
        records: worksheetDetails.map(worksheetDetail => {
          return {
            ...worksheetDetail.targetInventory.inventory,
            id: worksheetDetail.id,
            name: worksheetDetail.name,
            description: worksheetDetail.description,
            brand: worksheetDetail.targetInventory.inventory.product.brand,
            returnQty: worksheetDetail.targetInventory.returnQty,
            remark: worksheetDetail.targetInventory.remark,
            status: worksheetDetail.status,
            issue: worksheetDetail.issue
          }
        })
      }

      this._enableCartonLabel = await fetchSettingRule('enable-carton-label', partnerDomainId)
    }
  }

  _updateGristConfig() {
    const statusColumnConfig = {
      type: 'string',
      name: 'status',
      header: i18next.t('field.status'),
      width: 100
    }

    const issueColumnConfig = {
      type: 'string',
      name: 'issue',
      header: i18next.t('field.issue'),
      width: 200
    }

    const issueColumnIdx = this.preConfig?.columns?.findIndex(col => col.name === 'issue')
    const statusColumnIdx = this.preConfig?.columns?.findIndex(col => col.name === 'status')

    this.preConfig.columns.map(column => {
      if (column.name === 'description') {
        column.record = { ...column.record, editable: this._worksheetStatus === WORKSHEET_STATUS.DEACTIVATED.value }
      }
    })

    if (
      !this.preConfig.columns.some(e => e.name === 'status') &&
      this._worksheetStatus !== WORKSHEET_STATUS.DEACTIVATED.value
    ) {
      this.preConfig.columns = [...this.preConfig.columns, statusColumnConfig, issueColumnConfig]
    } else if (
      this.preConfig.columns.some(e => e.name === 'status') &&
      this._worksheetStatus === WORKSHEET_STATUS.DEACTIVATED.value
    ) {
      this.preConfig.columns.splice(issueColumnIdx)
      this.preConfig.columns.splice(statusColumnIdx)
    }

    this.config = { ...this.preConfig }
    this.data = { ...this.data }
  }

  _fillupForm(data) {
    for (let key in data) {
      Array.from(this.form.querySelectorAll('input, select')).forEach(field => {
        if (field.name === key && field.type === 'checkbox') {
          field.checked = data[key]
        } 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 _activateWorksheet() {
    try {
      const result = await CustomAlert({
        title: i18next.t('title.are_you_sure'),
        text: i18next.t('text.activate_return_worksheet'),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (!result.value) {
        return
      }

      const response = await client.mutate({
        mutation: gql`
          mutation ($worksheetNo: String!, $unloadingReturnWorksheetDetails: [WorksheetDetailPatch]) {
            activateUnloadingReturn(
              worksheetNo: $worksheetNo
              unloadingReturnWorksheetDetails: $unloadingReturnWorksheetDetails
            ) {
              name
            }
          }
        `,
        variables: {
          worksheetNo: this._worksheetNo,
          unloadingReturnWorksheetDetails: this._getExternalReturnWorksheetDetails()
        }
      })
      if (!response.errors) {
        this._showToast({ message: i18next.t('text.worksheet_activated') })
        await this.fetchWorksheet()
        this.updateContext()
        this._updateGristConfig()
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  _getExternalReturnWorksheetDetails() {
    return this.grist.dirtyData.records.map(worksheetDetail => {
      return {
        name: worksheetDetail.name,
        description: worksheetDetail.description
      }
    })
  }

  _openLotLabelPrintPopup() {
    const _pallets = {
      records: this.data.records.map(record => {
        return {
          id: record.id,
          palletId: record.palletId,
          batchId: record.batchId,
          product: record.product,
          palletQty: record.palletQty,
          printQty: record.palletQty,
          packingType: record.packingType,
          bizplace: this._bizplace
        }
      })
    }
    openPopup(html` <pallet-label-popup .pallets="${_pallets}"></pallet-label-popup> `, {
      backdrop: true,
      size: 'large',
      title: i18next.t('title.lot_label')
    })
  }

  _openCartonLabelPrintPopup() {
    openPopup(
      html` <carton-label-popup .fixedType="${'default'}" .bizplaceName="${this._bizplace}"></carton-label-popup> `,
      {
        backdrop: true,
        size: 'small',
        title: i18next.t('title.carton_label')
      }
    )
  }

  _showPutawayWorksheetPopup() {
    openPopup(
      html`
        <putaway-worksheet-generate-popup
          .crossDocking="${this.crossDocking}"
          .returnOrder="${this._returnOrder}"
          @completed="${async () => {
            await this.fetchWorksheet()
            this.updateContext()
          }}"
        ></putaway-worksheet-generate-popup>
      `,
      {
        backdrop: true,
        size: 'large',
        title: i18next.t('title.generate_putaway_worksheet')
      }
    )
  }

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

window.customElements.define('worksheet-unloading-return', WorksheetUnloadingReturn)
