import '@material/web/icon/icon.js'

import gql from 'graphql-tag'

import { css, html, LitElement } from 'lit'
import { customElement, property, query, state } from 'lit/decorators.js'

import { client } from '@operato/graphql'
import { i18next, localize } from '@operato/i18n'
import { isMobileDevice } from '@operato/utils'
import { DataGrist, FetchOption } from '@operato/data-grist'
import { CommonHeaderStyles } from '@operato/styles'

@customElement('attribute-set-item-list')
class AttributeSetItemList extends localize(i18next)(LitElement) {
  @property({ type: Object }) attribute: any

  @state() gristConfig: any

  static styles = [
    CommonHeaderStyles,
    css`
      :host {
        display: flex;
        flex-direction: column;

        background-color: var(--md-sys-color-surface);
      }

      ox-grist {
        flex: 1;
      }
    `
  ]

  @query('ox-grist') private grist!: DataGrist

  render() {
    return html`
      <ox-grist
        .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
        .config=${this.gristConfig}
        .fetchHandler=${this.fetchHandler.bind(this)}
      ></ox-grist>

      <div class="footer">
        <div filler></div>
        <button danger @click=${this.deleteAttributeSetItems.bind(this)}>
          <md-icon>delete_forever</md-icon>${i18next.t('button.delete')}
        </button>
        <button @click=${this.updateAttributeSetItems.bind(this)} done>
          <md-icon>save</md-icon>${i18next.t('button.save')}
        </button>
      </div>
    `
  }

  async firstUpdated() {
    this.gristConfig = {
      list: { fields: ['name', 'description', 'active'] },
      columns: [
        { type: 'gutter', gutterName: 'row-selector', multiple: true },
        {
          type: 'gutter',
          gutterName: 'button',
          icon: 'add',
          handlers: {
            click: 'record-copy'
          }
        },
        { type: 'gutter', gutterName: 'sequence' },
        {
          type: 'gutter',
          gutterName: 'button',
          icon: 'arrow_upward',
          handlers: {
            click: 'move-up'
          }
        },
        {
          type: 'gutter',
          gutterName: 'button',
          icon: 'arrow_downward',
          handlers: {
            click: 'move-down'
          }
        },
        {
          type: 'string',
          name: 'name',
          header: i18next.t('field.name'),
          record: {
            editable: true
          },
          width: 140
        },
        {
          type: 'string',
          name: 'description',
          header: i18next.t('field.description'),
          record: {
            editable: true
          },
          width: 180
        },
        {
          type: 'varname',
          name: 'tag',
          header: i18next.t('field.tag'),
          record: {
            editable: true
          },
          width: 180
        },
        {
          type: 'checkbox',
          name: 'active',
          label: true,
          header: i18next.t('field.active'),
          record: {
            editable: true
          },
          sortable: true,
          width: 60
        },
        {
          type: 'checkbox',
          name: 'hidden',
          label: true,
          header: i18next.t('field.hidden'),
          record: {
            editable: true
          },
          sortable: true,
          width: 60
        },
        {
          type: 'select',
          name: 'type',
          header: i18next.t('field.type'),
          record: {
            options: ['', 'number', 'text', 'select', 'boolean', 'date', 'datetime', 'file'],
            editable: true
          },
          width: 120
        },
        {
          type: 'parameters',
          name: 'options',
          header: i18next.t('field.options'),
          record: {
            editable: true,
            renderer: 'json5',
            options: async (value, column, record, row, field) => {
              return {
                name: record.type,
                help: '',
                spec:
                  record.type === 'select'
                    ? [
                        {
                          type: 'options' /* property-editor type */,
                          name: 'options',
                          label: 'options'
                        }
                      ]
                    : [],
                context: this.grist,
                objectified: true
              }
            }
          },
          width: 120
        }
      ],
      rows: {
        selectable: {
          multiple: true
        }
      },
      pagination: {
        infinite: true
      },
      sorters: []
    }
  }

  async fetchHandler({ filters, page, limit, sortings = [] }: FetchOption) {
    const attributes = this.attribute.items || []

    return {
      total: attributes.length,
      records: attributes
    }
  }

  private async updateAttributeSetItems() {
    this.grist.commit()

    const response = await client.mutate({
      mutation: gql`
        mutation ($id: String!, $patch: AttributeSetPatch!) {
          updateAttributeSet(id: $id, patch: $patch) {
            entity
          }
        }
      `,
      variables: {
        id: this.attribute.id,
        patch: {
          items: this.grist.data.records,
          cuFlag: 'M'
        }
      }
    })

    if (!response.errors) {
      await document.dispatchEvent(
        new CustomEvent('notify', {
          detail: {
            message: i18next.t('text.info_x_successfully', {
              x: i18next.t('button.save')
            })
          }
        })
      )
    }
  }

  private async deleteAttributeSetItems() {
    if (!confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
      return
    }

    this.grist.deleteSelectedRecords(false)
  }
}
