import '@things-factory/grist-ui'

import gql from 'graphql-tag'
import {
  css,
  html,
  LitElement
} from 'lit-element'
import { connect } from 'pwa-helpers/connect-mixin'

import {
  i18next,
  localize
} from '@things-factory/i18n-base'
import {
  client,
  store
} from '@things-factory/shell'
import { isMobileDevice } from '@things-factory/utils'

import { LOCATION_TYPE } from '../constants'

class SelectCcLocationPopup extends connect(store)(localize(i18next)(LitElement)) {
  static get properties() {
    return {
      bizplaceId: String,
      config: Object,
      data: Object,
      locations: Array,
      selectMultipleLocations: Boolean,
      _searchFields: Array,
      selectedLocation: Array
    }
  }

  static get styles() {
    return [
      css`
        :host {
          padding: 10px;
          display: flex;
          flex-direction: column;
          overflow-x: overlay;
          background-color: var(--main-section-background-color);
        }
        .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;
        }
        .button-container {
          padding: var(--button-container-padding);
          margin: var(--button-container-margin);
          text-align: var(--button-container-align);
          background-color: var(--button-container-background);
          height: var(--button-container-height);
        }
      `
    ]
  }

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

      <div class="grist">
      <data-grist
        id="location"
        .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
        .config=${this.config}
        .fetchHandler=${(params) => this.fetchLocations(this.selectedLocation, params)}
      ></data-grist>
      </div>

      <div class="button-container">
      <mwc-button
        raised
        @click="${this._selectLocation.bind(this)}"
        label="${i18next.t('button.select')}"
      ></mwc-button>
      </div>
    `
  }

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

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

  async firstUpdated() {
    this._searchFields = [
      {
        label: i18next.t('field.name'),
        name: 'name',
        type: 'text',
        props: { searchOper: 'i_like' }
      },
      {
        label: i18next.t('field.type'),
        name: 'type',
        type: 'select',
        options: [
          { value: '' },
          ...Object.values(LOCATION_TYPE)
            .map(type => {
              return {
                name: type.name,
                value: type.value
              }
            })
            .sort((a, b) => (a.name > b.name ? 1 : -1))
        ],
        props: { searchOper: 'eq' }
      }
    ]

    this.config = {
      pagination: { infinite: true },
      rows: {
        selectable: { multiple: this.selectMultipleLocations ? this.selectMultipleLocations : false },
        appendable: false
      },
      list: { fields: ['name', 'status'] },
      columns: [
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'gutter',
          gutterName: 'row-selector',
          multiple: this.selectMultipleLocations ? this.selectMultipleLocations : false
        },
        {
          type: 'string',
          name: 'name',
          header: i18next.t('field.name'),
          width: 150
        },
        {
          type: 'select',
          name: 'type',
          header: i18next.t('field.type'),
          record: {
            editable: true,
            options: [
              '',
              ...Object.values(LOCATION_TYPE)
                .map(type => type.value)
                .sort()
            ]
          },
          sortable: true,
          width: 150
        }
      ]
    }
  }

  async fetchLocations(selectedLocation) {
    try {
      let filters = this.searchForm.queryFilters || []
      if(selectedLocation.length > 0) {
        filters.push({
          name: 'locationId',
          operator: 'notin',
          value: selectedLocation.map(selectedLocation => selectedLocation.locationId)
        })
      }

      const { data, errors } = await client.query({
        query: gql`
          query locationByInventories($filters: [Filter!], $bizplaceId: String!) {
            locationByInventories(filters: $filters, bizplaceId: $bizplaceId) {
              items {
                id
                name
                type
              }
              total
            }
          }
        `,
        variables: { filters, bizplaceId: this.bizplaceId }
      })

      if (errors) {
        console.error(errors)
        throw new Error('Error fetching locations')
      }

      return {
        records: data.locationByInventories.items || [],
        total: data.locationByInventories.total || 0
      }
    } catch (e) {}
  }

  _selectLocation() {
    if (this.selectMultipleLocations !== true) {
      const selectedLocation = this.locationGrist.selected[0]
      if (selectedLocation) {
        this.dispatchEvent(
          new CustomEvent('location-selected', { detail: { location: selectedLocation, keyCode: 13 } })
        )
        history.back()
      } else {
        document.dispatchEvent(
          new CustomEvent('notify', { detail: { message: i18next.t('text.location_is_not_selected') } })
        )
      }
    } else {
      const selectedMultipleLocations = this.locationGrist.selected
      if (selectedMultipleLocations) {
        const multipleLocations = selectedMultipleLocations.map(itm => {
          return {
            location: {
              id: itm.id,
              name: itm.name,
              type: itm.type
            }
          }
        })

        this.dispatchEvent(
          new CustomEvent('location-selected', {
            detail: {
              multipleLocations
            }
          })
        )
        history.back()
      } else {
        document.dispatchEvent(
          new CustomEvent('notify', { detail: { message: i18next.t('text.location_is_not_selected') } })
        )
      }
    }
  }
}
window.customElements.define('select-cc-location-popup', SelectCcLocationPopup)
