import { MultiColumnFormStyles } from '@things-factory/form-ui'
import '@things-factory/grist-ui'
import { getRenderer } from '@things-factory/grist-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { client, 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 '../../components/popup-note'
import '../../components/vas-templates'
import { VAS_BATCH_AND_PRODUCT_TYPE, VAS_BATCH_NO_TYPE, VAS_ETC_TYPE, VAS_PRODUCT_TYPE } from '../../constants'

class RejectedReleaseOrder extends localize(i18next)(PageView) {
  static get properties() {
    return {
      _releaseOrderNo: String,
      _ownTransport: Boolean,
      _crossDocking: Boolean,
      _ganNo: String,
      _exportOption: Boolean,
      _courierOption: Boolean,
      _packingOption: Boolean,
      inventoryGristConfig: Object,
      vasGristConfig: Object,
      inventoryData: Object,
      vasData: Object,
      _template: Object,
      _rejectReason: String,
      _bizplaceName: String
    }
  }

  //vas --double check
  static get styles() {
    return [
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow-x: auto;
        }
        popup-note {
          flex: 1;
        }
        .container {
          display: flex;
          flex: 4;
        }
        .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;
        }
        .guide-container {
          max-width: 30vw;
          display: flex;
        }
        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);
        }
        [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`
      <popup-note
        .title="${i18next.t('title.rejection_reason')}"
        .value="${this._rejectReason}"
        .readonly="${true}"
      ></popup-note>
      <form name="releaseOrder" class="multi-column-form">
        <fieldset>
          <legend>${i18next.t('title.release_order_no')}: ${this._releaseOrderNo}</legend>

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

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

            <input id="courierOption" type="checkbox" name="courierOption" ?checked="${this._courierOption}" disabled />
            <label>${i18next.t('label.courier')}</label>

            <input id="packingOption" type="checkbox" name="packingOption" ?checked="${this._packingOption}" disabled />
            <label>${i18next.t('label.packing')}</label>

            <input id="exportOption" type="checkbox" name="exportOption" ?checked="${this._exportOption}" disabled />
            <label>${i18next.t('label.export')}</label>

            ${this._crossDocking
              ? html`
                  <input
                    id="crossDocking"
                    type="checkbox"
                    name="crossDocking"
                    ?checked="${this._crossDocking}"
                    disabled
                  />
                  <label for="crossDocking">${i18next.t('label.cross_docking')}</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.ref_no_2')}</label>
          <input name="refNo2" readonly />

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

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

          <label ?hidden="${!this._ownTransport}">${i18next.t('label.co_no')}</label>
          <input name="collectionOrderNo" ?hidden="${!this._ownTransport}" readonly />

          ${this._crossDocking
            ? html`
                <label for="ganNo">${i18next.t('label.arrival_notice')}</label>
                <input readonly name="ganNo" value="${this._ganNo}" />
              `
            : ''}
          ${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="so-form-container" ?hidden="${!this._exportOption || (this._exportOption && !this._ownTransport)}">
        <form name="shippingOrder" class="multi-column-form">
          <fieldset>
            <legend>${i18next.t('title.export_order')}</legend>
            <label>${i18next.t('label.container_no')}</label>
            <input name="containerNo" readonly />

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

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

            <label>${i18next.t('label.ship_name')}</label>
            <input name="shipName" readonly />
          </fieldset>
        </form>
      </div>

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

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

          <h2><mwc-icon>list_alt</mwc-icon>${i18next.t('title.vas')}</h2>
          <data-grist
            id="vas-grist"
            .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
            .config=${this.vasGristConfig}
            .data="${this.vasData}"
          ></data-grist>
        </div>
        <div class="guide-container">${this._template}</div>
      </div>
    `
  }

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

  get context() {
    return {
      title: i18next.t('title.rejected_release_order'),
      actions: [
        {
          title: i18next.t('button.back'),
          action: () => history.back(),
          ...CommonButtonStyles.back
        }
      ]
    }
  }

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

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

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

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

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

  pageUpdated(changes) {
    if (this.active && changes.resourceId) {
      this._releaseOrderNo = changes.resourceId
      this._fetchReleaseOrder()
    }
  }

  pageInitialized() {
    this.inventoryGristConfig = {
      pagination: { infinite: true },
      rows: { selectable: { multiple: true }, appendable: false },
      list: { fields: ['name', 'batchId', 'product', 'location', 'releaseQty'] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'string',
          name: 'batchId',
          header: i18next.t('field.batch_id'),
          width: 100
        },
        {
          type: 'string',
          name: 'productName',
          header: i18next.t('field.product'),
          width: 150
        },
        {
          type: 'code',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          record: {
            codeName: 'PACKING_TYPES'
          },
          width: 150
        },
        {
          type: 'float',
          name: 'qty',
          header: i18next.t('field.available_qty'),
          width: 100
        },
        {
          type: 'float',
          name: 'releaseQty',
          header: i18next.t('field.release_qty'),
          record: { options: { min: 0 } },
          width: 100
        },
        {
          type: 'string',
          name: 'remainUomValue',
          header: i18next.t('field.available_uom_value'),
          width: 100
        },
        {
          type: 'string',
          name: 'releaseUomValue',
          header: i18next.t('field.release_uom_value'),
          record: { options: { min: 0 } },
          width: 100
        },
        {
          type: 'string',
          name: 'batchIdRef',
          header: i18next.t('field.batch_no_ref'),
          width: 100
        }
      ]
    }

    this.vasGristConfig = {
      list: { fields: ['targetType', 'targetDisplay', 'packingType'] },
      pagination: { infinite: true },
      rows: {
        appendable: false,
        handlers: {
          click: (columns, data, column, record, rowIndex) => {
            if (record && record.vas && record.vas.operationGuideType === 'template') {
              this._template = document.createElement(record.vas.operationGuide)
              this._template.record = { ...record, operationGuide: JSON.parse(record.operationGuide) }
            } else {
              this._template = null
            }
          }
        }
      },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'string',
          name: 'set',
          header: i18next.t('field.set'),
          width: 100
        },
        {
          type: 'string',
          name: 'targetType',
          header: i18next.t('field.target_type'),
          width: 150
        },
        {
          type: 'string',
          name: 'target',
          header: i18next.t('field.target'),
          record: {
            renderer: (value, column, record, rowIndex, field) => {
              if (record.targetType === VAS_BATCH_NO_TYPE) {
                return getRenderer()(record.targetBatchId, column, record, rowIndex, field)
              } else if (record.targetType === VAS_PRODUCT_TYPE) {
                return getRenderer('object')(record.targetProduct, column, record, rowIndex, field)
              } else if (record.targetType === VAS_BATCH_AND_PRODUCT_TYPE) {
                return getRenderer()(
                  `${record.targetBatchId} / ${record.targetProduct.name}`,
                  column,
                  record,
                  rowIndex,
                  field
                )
              } else if (record.targetType === VAS_ETC_TYPE) {
                return getRenderer()(record.otherTarget, column, record, rowIndex, field)
              }
            }
          },

          width: 250
        },
        {
          type: 'string',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          width: 250
        },
        {
          type: 'integer',
          name: 'qty',
          header: i18next.t('field.qty'),
          width: 100
        },
        {
          type: 'integer',
          name: 'uomValue',
          header: i18next.t('field.uom_value'),
          width: 100
        },
        {
          type: 'object',
          name: 'vas',
          header: i18next.t('field.vas'),
          record: { options: { queryName: 'vass' } },
          width: 250
        },
        {
          type: 'string',
          name: 'status',
          header: i18next.t('field.status'),
          width: 150
        },
        {
          type: 'string',
          name: 'remark',
          header: i18next.t('field.remark'),
          width: 350
        },
        {
          type: 'string',
          name: 'description',
          header: i18next.t('field.comment'),
          width: 350
        }
      ]
    }
  }

  async _fetchReleaseOrder() {
    const response = await client.query({
      query: gql`
        query releaseGoodDetail($name: String!) {
          releaseGoodDetail(name: $name) {
            name
            truckNo
            bizplace {
              id
              name
            }
            status
            ownTransport
            crossDocking
            arrivalNotice {
              name
            }
            exportOption
            courierOption
            packingOption
            releaseDate
            refNo
            refNo2
            refNo3
            collectionOrderNo
            remark
            attachment {
              id
              name
              refBy
              path
              mimetype
            }
            inventoryInfos {
              batchId
              batchIdRef
              productName
              packingType
              qty
              uomValue
              releaseQty
              releaseUomValue
              uom
            }
            shippingOrder {
              name
              description
              containerNo
              containerLeavingDate
              containerArrivalDate
              shipName
            }
            orderVass {
              vas {
                name
                operationGuide
                operationGuideType
              }
              set
              targetType
              targetBatchId
              targetProduct {
                id
                name
                description
              }
              packingType
              qty
              uomValue
              otherTarget
              description
              remark
              status
              operationGuide
            }
          }
        }
      `,
      variables: { name: this._releaseOrderNo }
    })

    if (!response.errors) {
      const releaseOrder = response.data.releaseGoodDetail
      const shippingOrder = releaseOrder.shippingOrder
      const orderInventories = releaseOrder.inventoryInfos.map(inventoryInfo => {
        return {
          ...inventoryInfo,
          remainUomValue: inventoryInfo.uomValue + ' ' + inventoryInfo.uom,
          releaseUomValue: inventoryInfo.releaseUomValue + ' ' + inventoryInfo.uom
        }
      })
      const orderVass = releaseOrder.orderVass

      this._exportOption = releaseOrder.exportOption
      this._bizplaceName = releaseOrder.bizplace.name
      if (this._exportOption) {
        this._ownTransport = true
      } else if (!this._exportOption) {
        this._ownTransport = releaseOrder.ownTransport
      }

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

      this._courierOption = response.data.releaseGoodDetail.courierOption
      this._packingOption = response.data.releaseGoodDetail.packingOption
      this._crossDocking = response.data.releaseGoodDetail?.crossDocking
      this._ganNo = response.data.releaseGoodDetail?.arrivalNotice?.name

      this._rejectReason = releaseOrder.remark
      this._fillupRGForm(releaseOrder)
      if (this._exportOption) this._fillupSOForm(shippingOrder)

      this.inventoryData = { records: orderInventories }
      this.vasData = {
        records: orderVass
          .sort((a, b) => a.set - b.set)
          .map(orderVas => {
            return {
              ...orderVas,
              set: `Set ${orderVas.set}`
            }
          })
      }
    }
  }

  _fillupRGForm(data) {
    this._fillupForm(this.releaseOrderForm, data)
  }

  _fillupSOForm(data) {
    this._fillupForm(this.shippingOrderForm, data)
  }

  _fillupForm(form, data) {
    for (let key in data) {
      Array.from(form.querySelectorAll('input, textarea, select')).forEach(field => {
        if (field.name === key && field.type === 'checkbox') {
          field.checked = data[key]
        } else if (field.name === key) {
          field.value = data[key]
        }
      })
    }
  }

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

window.customElements.define('rejected-release-order', RejectedReleaseOrder)
