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 } from '@things-factory/shell'
import { ScrollbarStyles } from '@things-factory/styles'
import { isMobileDevice } from '@things-factory/utils'

class TargetProductSelectorPopup extends localize(i18next)(LitElement) {
  static get properties() {
    return {
      _searchFields: Array,
      productGristConfig: Object,
      productDetailGristConfig: Object,
      data: Object
    }
  }

  static get styles() {
    return [
      ScrollbarStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: hidden;
        }

        search-form {
          overflow: visible;
        }

        .grist-container {
          overflow-y: hidden;
          display: flex;
          flex: 1;
        }

        .grist {
          background-color: var(--main-section-background-color);
          display: flex;
          flex-direction: column;
          overflow-y: auto;
        }

        .grist-product-list {
          flex: 3;
        }

        .grist-product-detail-list {
          flex: 2;
        }

        data-grist {
          overflow-y: auto;
          flex: 1;
        }
      `
    ]
  }

  render() {
    return html`
      <search-form
        id="search-form"
        .fields=${this._searchFields}
        @submit=${e => this.productGrist.fetch()}
      ></search-form>

      <div class="grist-container">
        <div class="grist grist-product-list">
          <data-grist
            id="product_grist"
            .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
            .config=${this.productGristConfig}
            .fetchHandler="${this._getMyProducts.bind(this)}"
          ></data-grist>
        </div>
        <div class="grist grist-product-detail-list">
          <data-grist
            id="product_detail_grist"
            .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
            .config=${this.productDetailConfig}
            .data="${this.productDetailsData}"
          ></data-grist>
        </div>
      </div>
    `
  }

  async firstUpdated(e) {
    this.productGristConfig = {
      pagination: { limit: 50, pages: [10, 20, 50, 100] },
      list: { fields: ['sku', 'brandSku', 'name', 'description', 'type'] },
      rows: {
        handlers: {
          click: (columns, data, column, record, rowIndex) => {
            this._fetchProductDetails(record.id)
          }
        }
      },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'string',
          name: 'id',
          hidden: true
        },
        {
          type: 'string',
          name: 'sku',
          header: i18next.t('field.sku'),
          sortable: true,
          width: 180
        },
        {
          type: 'string',
          name: 'brandSku',
          header: i18next.t('field.brand_sku'),
          sortable: true,
          width: 180
        },
        {
          type: 'string',
          name: 'name',
          header: i18next.t('field.name'),
          sortable: true,
          width: 180
        },
        {
          type: 'string',
          name: 'description',
          header: i18next.t('field.description'),
          sortable: true,
          width: 300
        },
        {
          type: 'select',
          name: 'type',
          header: i18next.t('field.type'),
          sortable: true,
          width: 120
        }
      ]
    }

    this.productDetailGristConfig = {
      rows: {
        appendable: true,
        classifier: record => {
          return {
            emphasized: record.error || false
          }
        }
      },
      pagination: { infinite: true },
      list: {
        fields: ['isDefault', 'gtin', 'packingType', 'uom', 'uomValue', 'packingSize']
      },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'boolean',
          name: 'isDefault',
          header: i18next.t('field.default'),
          sortable: true,
          width: 80
        },
        {
          type: 'string',
          name: 'gtin',
          header: i18next.t('field.gtin'),
          sortable: true,
          width: 180
        },
        {
          type: 'select',
          name: 'packingType',
          header: i18next.t('field.packing_type'),
          width: 120
        },
        {
          type: 'select',
          name: 'uom',
          header: `${i18next.t('field.uom')}`,
          width: 80
        },
        {
          type: 'float',
          name: 'uomValue',
          header: `${i18next.t('field.uom_value')}`,
          width: 100
        },
        {
          type: 'float',
          name: 'packingSize',
          header: i18next.t('field.packing_size'),
          width: 110
        }
      ]
    }

    this._searchFields = [
      {
        label: i18next.t('field.product_info'),
        name: 'product_info',
        props: {
          searchOper: 'i_like'
        }
      },
      {
        label: i18next.t('field.type'),
        name: 'type',
        props: {
          searchOper: 'i_like'
        }
      }
    ]
  }

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

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

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

  async _getMyProducts({ page, limit, sorters = [{ name: 'sku' }], filters = [] }) {
    const pagination = { page, limit }
    const sortings = sorters

    const response = await client.query({
      query: gql`
        query myBizplaceProducts($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
          myBizplaceProducts(filters: $filters, pagination: $pagination, sortings: $sortings) {
            items {
              id
              sku
              name
              description
              brandSku
              type
            }
            total
          }
        }
      `,
      variables: { filters, pagination, sortings }
    })

    if (!response.errors) {
      return {
        total: response.data.myBizplaceProducts.total || 0,
        records:
          response.data.myBizplaceProducts.items.map(itm => {
            return {
              ...itm,
              productRef: { name: itm?.productRef ? '(' + itm.productRef.sku + ') ' + itm.productRef.name : '' }
            }
          }) || []
      }
    }
  }

  async _fetchProductDetails(productId) {
    try {
      if (!productId || productId == '') return

      const filters = [{ name: 'product', operator: 'eq', value: productId }]
      const response = await client.query({
        query: gql`
          query productDetails($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
            productDetails(filters: $filters, pagination: $pagination, sortings: $sortings) {
              items {
                id
                isDefault
                gtin
                packingType
                uom
                uomValue
                packingSize
              }
              total
            }
          }
        `,
        variables: {
          filters,
          pagination: { page: 0, limit: 9999 },
          sortings: [{ name: 'sku' }]
        }
      })

      let data = this._updateRowOption(response.data.productDetails.items)

      if (!response.errors) {
        this._data = {
          total: response.data.productDetails.total || 0,
          records: data
        }
      }
    } catch (e) {
      this._showToast(e)
    }
  }

  _selectBizplace() {
    const selectedBizplace = this.dataGrist.selected.length

    if (selectedBizplace) {
      this.dispatchEvent(
        new CustomEvent('selected', {
          detail: {
            ...this.dataGrist.selected[0]
          }
        })
      )
      history.back()
    } else {
      document.dispatchEvent(
        new CustomEvent('notify', {
          detail: {
            message: i18next.t('text.bizplace_is_not_selected')
          }
        })
      )
    }
  }

  _dblClickHandler(columns, data, column, record, rowIndex, target) {
    this.dispatchEvent(new CustomEvent('selected', { detail: record }))
    history.back()
  }
}

window.customElements.define('target-product-selector-popup', TargetProductSelectorPopup)
