import '@things-factory/form-ui'
import '@things-factory/grist-ui'

import gql from 'graphql-tag'
import { css, html, LitElement } from 'lit-element'

import { i18next, localize } from '@things-factory/i18n-base'
import { client, CustomAlert, gqlContext } from '@things-factory/shell'
import { ScrollbarStyles } from '@things-factory/styles'
import { flattenObject, isMobileDevice } from '@things-factory/utils'

export class ProductDetailBizplaceSettingPopup extends localize(i18next)(LitElement) {
  static get styles() {
    return [
      ScrollbarStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: hidden;
          background-color: white;

          --grid-record-emphasized-background-color: #ffdbdb;
          --grid-record-emphasized-color: #703f3f;
        }
        search-form {
          overflow: visible;
        }
        data-grist {
          overflow-y: auto;
          flex: 1;
        }
        .button-container {
          padding: 10px 0 12px 0;
          text-align: center;
        }
        [danger] {
          --mdc-theme-primary: var(--mdc-danger-button-primary-color);
        }
        .header {
          display: grid;
          grid-template-columns: repeat(24, 1fr);
          grid-gap: var(--form-grid-gap);
          grid-auto-rows: minmax(24px, auto);
          max-width: var(--form-multi-column-max-width);
          margin-top: var(--form-margin);
          margin-left: var(--form-margin);
          margin-right: var(--form-margin);
        }
        .header legend {
          grid-column: span 24;
          text-transform: capitalize;

          padding: var(--legend-padding);
          font: var(--legend-font);
          color: var(--legend-text-color);
          border-bottom: var(--legend-border-bottom);
        }
      `
    ]
  }

  static get properties() {
    return {
      _searchFields: Array,
      config: Object,
      _data: Object,
      productId: String
    }
  }

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

  get buttonSave() {
    return this.shadowRoot.querySelector('#buttonSave')
  }

  render() {
    return html`
      <data-grist
        .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
        .config=${this.config}
        .data=${this._data}
        .fetchHandler="${this.fetchHandler.bind(this)}"
        @field-change="${this._fieldChange.bind(this)}"
      ></data-grist>

      <div class="button-container">
        <mwc-button
          id="buttonSave"
          @click=${this._updateProductDetailBizplaceSettings}
          raised
          label="${i18next.t('button.save')}"
        ></mwc-button>
        <mwc-button
          raised
          danger
          @click=${() => {
            history.back()
          }}
          label="${i18next.t('button.back')}"
        ></mwc-button>
      </div>
    `
  }

  async firstUpdated() {
    this.config = {
      rows: {
        appendable: false
      },
      pagination: { infinite: true },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'boolean',
          name: 'productDetail|isDefault',
          header: i18next.t('field.default'),
          record: { align: 'center' },
          width: 80
        },
        {
          type: 'string',
          name: 'productDetail|gtin',
          header: i18next.t('field.gtin'),
          sortable: true,
          width: 180
        },
        {
          type: 'string',
          name: 'productDetail|refCode',
          header: i18next.t('field.ref_code'),
          sortable: true,
          width: 150
        },
        {
          type: 'string',
          name: 'productDetail|packingType',
          header: i18next.t('field.packing_type'),
          width: 120
        },
        {
          type: 'string',
          name: 'productDetail|uom',
          header: `${i18next.t('field.uom')}`,
          width: 80
        },
        {
          type: 'float',
          name: 'productDetail|uomValue',
          header: `${i18next.t('field.uom_value')}`,
          width: 100
        },
        // {
        //   type: 'boolean',
        //   name: 'requirePacking',
        //   header: `*${i18next.t('field.require_packing')}`,
        //   record: { align: 'center', editable: true },
        //   width: 200
        // },
        // {
        //   type: 'float',
        //   name: 'bufferQty',
        //   record: { editable: true },
        //   header: `*${i18next.t('field.buffer_qty')}`,
        //   width: 95
        // },
        {
          type: 'float',
          name: 'minQty',
          record: { editable: true, options: { min: 0 } },
          header: `*${i18next.t('field.min_qty')}`,
          width: 80
        },
        {
          type: 'float',
          name: 'maxQty',
          record: { editable: true, options: { min: 0 } },
          header: `*${i18next.t('field.max_qty')}`,
          width: 80
        }
      ]
    }
  }

  async fetchHandler({ page, limit, sorters = [] }) {
    try {
      if (!this.productId) return

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

      const filters = [{ name: 'product_id', operator: 'eq', value: this.productId }]

      const response = await client.query({
        query: gql`
          query productDetailBizplaceSettings($filters: [Filter], $pagination: Pagination, $sortings: [Sorting]) {
            productDetailBizplaceSettings(filters: $filters, pagination: $pagination, sortings: $sortings) {
              items {
                id
                name
                productDetail {
                  id
                  gtin
                  refCode
                  packingType
                  uom
                  uomValue
                  isDefault
                  product {
                    id
                    sku
                    name
                    description
                  }
                }
                requirePacking
                bufferQty
                minQty
                maxQty
              }
              total
            }
          }
        `,
        variables: { filters, pagination, sortings },
        context: gqlContext()
      })

      if (!response.errors) {
        this._data = {
          total: response.data.productDetailBizplaceSettings.total || 0,
          records: response.data.productDetailBizplaceSettings.items.map(itm => {
            return { ...itm, ...flattenObject(itm) }
          })
        }
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  _fieldChange(e) {
    var { after, before, column, record, row } = e.detail
    let updatedRecords = {
      ...this.dataGrist._data
    }

    if (column.record?.options?.min > after) {
      this.dataGrist._data.records[row][column.name] = before
      updatedRecords = {
        ...this.dataGrist._data
      }

      this._showToast({ type: 'error', message: `Minimum value of ${column.record.options.min} is required.` })
    }

    this._data = { ...updatedRecords }
  }

  async _updateProductDetailBizplaceSettings() {
    try {
      // this.buttonSave.disabled = true
      this.dataGrist.showSpinner()

      let data = this._data
      let grist = this.dataGrist

      let patches = this.dataGrist._data.records.map(itm => {
        return {
          id: itm.id,
          bufferQty: itm.bufferQty || 0,
          minQty: itm.minQty,
          maxQty: itm.maxQty,
          requirePacking: itm.requirePacking || false,
          productDetail: { id: itm.productDetail.id }
        }
      })

      let productId = this.productId

      if (!productId) throw new Error('Product not found')

      if (productId && patches) {
        const response = await client.mutate({
          mutation: gql`
            mutation updateMultipleProductDetailBizplaceSetting(
              $productId: String!
              $patches: [ProductDetailBizplaceSettingPatch]!
            ) {
              updateMultipleProductDetailBizplaceSetting(productId: $productId, patches: $patches) {
                name
              }
            }
          `,
          variables: { productId, patches },
          context: gqlContext()
        })
        if (response.errors) {
          throw response.errors
        }
      } else {
        CustomAlert({
          title: i18next.t('text.nothing_changed'),
          text: i18next.t('text.there_is_nothing_to_save')
        })
      }

      this.dataGrist.hideSpinner()
      this.buttonSave.disabled = false
      this.dispatchEvent(new CustomEvent('saved', {}))
      history.back()
    } catch (error) {
      this._showToast(error)
      this.dataGrist.hideSpinner()
      this.buttonSave.disabled = false
    }
  }

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

window.customElements.define('product-detail-bizplace-setting-popup', ProductDetailBizplaceSettingPopup)
