import '@things-factory/form-ui'
import '@things-factory/grist-ui'
import { client, CustomAlert, navigate, PageView } from '@things-factory/shell'
import { css, html } from 'lit-element'
import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
import { i18next, localize } from '@things-factory/i18n-base'
import { MultiColumnFormStyles } from '@things-factory/form-ui'
import { openPopup } from '@things-factory/layout-base'
import { ORDER_TYPES, ORDER_STATUS, TRANSFER_TYPES } from '../../constants'
import gql from 'graphql-tag'

class ReceiveTransferOrderRequest extends localize(i18next)(PageView) {
  static get styles() {
    return [
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow-x: auto;
        }
        .container {
          flex: 1;
          display: flex;
        }
        .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);
        }

        .gan-preview {
          display: flex;
          flex-direction: row;
          flex: 1;
        }
        attachment-viewer {
          flex: 1;
        }
      `
    ]
  }

  static get properties() {
    return {
      config: Object,
      data: Object,
      productData: Object,
      _ownTransport: Boolean,
      _status: String,
      _toNo: String,
      _status: String
    }
  }

  constructor() {
    super()
    this.productData = { records: [] }
  }

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

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

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

          <label>${i18next.t('label.status')}</label>
          <select name="status" disabled>
            ${Object.keys(ORDER_STATUS).map(key => {
              const status = ORDER_STATUS[key]
              return html` <option value="${status.value}">${i18next.t(`label.${status.name}`)}</option> `
            })}
          </select>

          <label>${i18next.t('label.type')}</label>
          <select name="type" disabled>
            ${Object.keys(TRANSFER_TYPES).map(key => {
              const type = TRANSFER_TYPES[key]
              return html` <option value="${type.value}">${i18next.t(`label.${type.name}`)}</option> `
            })}
          </select>

          <input
            id="ownTransport"
            type="checkbox"
            name="ownTransport"
            ?checked="${this._ownTransport}"
            @change="${e => (this._ownTransport = e.currentTarget.checked)}"
            disabled
          />
          <label>${i18next.t('label.own_transport')}</label>
        </fieldset>
      </form>

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

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

    if (this._status === ORDER_STATUS.PENDING_RECEIVE.value) {
      actions.push(
        {
          title: i18next.t('button.reject'),
          action: this._rejectTransferOrder.bind(this),
          ...CommonButtonStyles.reject
        },
        {
          title: i18next.t('button.receive'),
          action: this._receiveTransferOrder.bind(this)
        }
      )
    }

    return {
      title: i18next.t('title.transfer_order_detail'),
      actions,
      exportable: {
        name: i18next.t('title.transfer_order_detail'),
        data: this._exportableData.bind(this)
      }
    }
  }

  async pageUpdated(changes, lifecycle) {
    if (this.active) {
      this._toNo = changes.resourceId || this._toNo || ''
      await this._fetchTO()
      this.updateContext()
    }
  }

  async pageInitialized() {
    this.config = {
      rows: { selectable: { multiple: true }, appendable: false },
      list: { fields: ['name', 'bizplace', 'releaseDate', 'status', 'updatedAt'] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'string',
          name: 'batchId',
          header: i18next.t('field.batch_id'),
          record: { align: 'left' },
          width: 100
        },
        {
          type: 'object',
          name: 'product',
          header: i18next.t('field.product'),
          record: { align: 'center', options: { queryName: 'products' } },
          width: 350
        },
        {
          type: 'string',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          record: { align: 'center' },
          width: 150
        },
        {
          type: 'float',
          name: 'weight',
          header: i18next.t('field.weight'),
          record: { align: 'center', options: { min: 0 } },
          width: 100
        },
        {
          type: 'string',
          name: 'unit',
          header: i18next.t('field.unit'),
          record: { align: 'center' },
          width: 150
        },
        {
          type: 'float',
          name: 'packQty',
          header: i18next.t('field.pack_qty'),
          record: { align: 'center', options: { min: 0 } },
          width: 100
        },
        {
          type: 'float',
          name: 'totalWeight',
          header: i18next.t('field.total_weight'),
          record: { align: 'center', options: { min: 0 } },
          width: 100
        },
        {
          type: 'string',
          name: 'status',
          header: i18next.t('field.status'),
          record: { align: 'center' },
          width: 150
        }
      ]
    }
  }

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

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

  _fillupTOForm(data) {
    this._fillupForm(this.transferOrderForm, data)
  }

  _fillupForm(form, data) {
    form.reset()
    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.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 _fetchTO() {
    if (!this._toNo) return

    try {
      const response = await client.query({
        query: gql`
          query transferOrder($name: String!) {
            transferOrder(name: $name) {
              bizplace {
                name
                description
              }
              name
              issuedDate
              status
              refNo
              type
              ownTransport
              orderInventories {
                batchId
                status
                product {
                  sku
                  name
                  description
                }
              }
              updatedAt
            }
          }
        `,
        variables: {
          name: this._toNo
        }
      })

      if (!response.errors) {
        const transferOrder = response.data.transferOrder
        const orderVass = transferOrder.orderVass
        const orderInventories = transferOrder.orderInventories
        this._ownTransport = transferOrder.ownTransport
        this._status = transferOrder.status
        this.productData = { records: orderInventories }
        this._fillupTOForm(transferOrder)
      }
    } catch (e) {
      this._showToast(e)
    }
  }

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

      if (!result.value) {
        return
      }

      const response = await client.mutate({
        mutation: gql`
          mutation generateReleaseGoodWorksheet($orderNo: String!, $orderType: String!) {
            generateReleaseGoodWorksheet(orderNo: $orderNo, orderType: $orderType) {
              pickingWorksheet {
                name
              }
            }
          }
        `,
        variables: {
          orderNo: this._toNo,
          orderType: ORDER_TYPES.TRANSFER_ORDER.value
        }
      })

      if (!response.errors) {
        navigate(`single_outbound_worksheets`)
        this._showToast({ message: i18next.t('text.transfer_order_received') })
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  // async _rejectTransferOrder() {
  //   const popup = openPopup(
  //     html`
  //       <popup-note
  //         .title="${i18next.t('title.remark')}"
  //         @submit="${async e => {
  //           try {
  //             if (!e.detail.value) throw new Error(i18next.t('text.remark_is_empty'))
  //             const result = await CustomAlert({
  //               title: i18next.t('title.are_you_sure'),
  //               text: i18next.t('text.reject_transfer_order'),
  //               confirmButton: { text: i18next.t('button.confirm') },
  //               cancelButton: { text: i18next.t('button.cancel') }
  //             })

  //             if (!result.value) {
  //               return
  //             }

  //             const response = await client.query({
  //               query: gql`
  //               mutation {
  //                 rejectTransferOrder(${gqlBuilder.buildArgs({
  //                   name: this._toNo,
  //                   patch: { remark: e.detail.value }
  //                 })}) {
  //                   name
  //                 }
  //               }
  //             `
  //             })

  //             if (!response.errors) {
  //               navigate('transfer_order_requests')
  //               this._showToast({ message: i18next.t('text.transfer_order_rejected') })
  //             }
  //           } catch (e) {
  //             this._showToast(e)
  //           }
  //         }}"
  //       ></popup-note>
  //     `,
  //     {
  //       backdrop: true,
  //       size: 'medium',
  //       title: i18next.t('title.reject_transfer_order')
  //     }
  //   )

  //  
  // }

  get _columns() {
    return this.config.columns
  }

  _exportableData() {
    return this.dataGrist.exportRecords()
  }

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

window.customElements.define('receive-transfer-order-request', ReceiveTransferOrderRequest)
