import '@things-factory/grist-ui'

import gql from 'graphql-tag'
import { SingleColumnFormStyles } from '@things-factory/form-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client, CustomAlert } from '@things-factory/shell'
import { ScrollbarStyles } from '@things-factory/styles'
import { css, html, LitElement } from 'lit-element'
import { sleep } from '@operato/utils'
import '../order/vas-order/popup/order-vas-popup'

class addVasOrderLevel extends localize(i18next)(LitElement) {
  static get properties() {
    return {
      config: Object,
      data: Object,
      bizplaceId: String,
      orderNo: String,
      vasData: Array,
      newVasData: Array
    }
  }

  static get styles() {
    return [
      css`
        :host {
          display: flex;
          flex-direction: column;
          width: 100%;
          overflow: hidden;
          background-color: white;
        }

        .card {
          margin: 10px;
          background-color: rgb(255, 255, 255);
          min-height: 200px;
          position: relative;
          border-radius: 10px;
          border: 2px solid rgb(20, 154, 155);
          padding: 10px;
        }

        .container {
          overflow-y: auto;
          height: 100%;
        }

        .card-content-group {
          margin-bottom: 10px;
        }

        input[type='text' i] {
          padding: 4px 2px;
        }

        input[id='vasName' i] {
          border-width: inherit;
        }

        #close {
          display: inline-block;
          padding: 2px 5px;
          margin-top: 3px;
          margin-right: 3px;
          background: #696969;
          border-radius: 50%;
          font-size: 8px;
          color: white;
        }

        label {
          color: #3a5877;
        }

        .button button {
          width: 20px;
          height: 20px;
          border-radius: 50%;
          background-color: #909090;
          color: white;
          border: none;
          outline: none;
          cursor: pointer;
          display: flex;
          justify-content: center;
          align-items: center;
          float: right;
          margin-right: 10px;
          margin-top: 5px;
        }

        .button-container {
          padding: var(--button-container-padding);
          text-align: var(--button-container-align);
          background-color: var(--button-container-background);
          height: var(--button-container-height);
        }
      `
    ]
  }

  constructor() {
    super()
    this.vasData = []
  }

  render() {
    return html` <div class="container">
      ${this.vasData.map((vas, index) => {
        return html` <div class="card">
          <div class="button">
            <!-- remove vas card -->
            <button id="closeButton" @click=${this.handleRemoveVas.bind(this)} data-index="${index}">X</button>
          </div>
          <div>
            <form>
              <input type="hidden" id="orderVasId" .value=${vas.orderVasId} />
              <input type="hidden" id="vasId" .value=${vas.vassId} />
              <div class="card-content-group">
                <label>${i18next.t('label.vas_name')}</label><br />
                <input type="text" id="vasName" .value=${vas.name} readonly />
              </div>
              <div class="card-content-group">
                <label>${i18next.t('label.vas_qty')}</label><br />
                <input type="number" id="vasQty-${index}" .value=${vas.vasQty} />
              </div>
              <div class="card-content-group">
                <label>${i18next.t('label.vasRemark')}</label><br />
                <textarea type="text" id="vasRemark-${index}" .value=${vas.vasRemark}></textarea>
              </div>
            </form>
          </div>
        </div>`
      })}</div>
      <div class="button-container">
        <mwc-button
          @click=${this.addOrderVas.bind(this)}
          label="${`${i18next.t('button.add_new')}`}"
          raised
        ></mwc-button>

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

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

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

  async firstUpdated() {
    this.config = {}
    await this.fetchOrderVas()
  }

  //fetch orderVasItem based on roNumber
  async fetchOrderVas() {
    if (!this.orderNo) return

    const response = await client.query({
      query: gql`
        query orderVasList($bizplaceId: String!, $orderNo: String!) {
          orderVasList(bizplaceId: $bizplaceId, orderNo: $orderNo) {
            items {
              orderVas {
                id
              }
              vassId
              vasName
              vasQty
              vasRemark
            }
          }
        }
      `,
      variables: { bizplaceId: this.bizplaceId, orderNo: this.orderNo }
    })

    if (!response.errors) {
      this.vasData = response.data.orderVasList.items.map(item => ({
        orderVasId: item.orderVas.id,
        vassId: item.vassId,
        name: item.vasName,
        vasQty: item.vasQty,
        vasRemark: item.vasRemark,
        originalVasQty: item.vasQty,
        originalVasRemark: item.vasRemark
      }))
    }
  }

  async addOrderVas() {
    await sleep(1010)
    try {
      openPopup(
        html` <order-vas-popup
          .bizplaceId="${this.bizplaceId}"
          @selected="${e => {
            this.newVasData = e.detail
            this.addVasData(this.newVasData)
          }}"
        ></order-vas-popup>`,
        {
          backdrop: true,
          size: 'large',
          title: i18next.t('title.vas')
        }
      )
    } catch (e) {
      this.showToast(e)
    }
  }

  addVasData(newVas) {
    let oldVas = this.vasData || []

    oldVas = newVas.reduce((acc, curr) => {
      const sameVas = acc.find(item => item.vassId === curr.id)
      if (!sameVas) {
        acc.push({
          orderVasId: curr.orderVasId || null,
          vassId: curr.id,
          name: curr.name,
          vasQty: 0,
          vasRemark: ''
        })
      }
      return acc
    }, oldVas)

    this.vasData = oldVas
  }

  async updateOrderVas() {
    if (!this.orderNo) return

    const orderVasPatch = await this.getVasOrderPatch()
    if (!orderVasPatch || orderVasPatch.length === 0) {
      return
    }

    if (orderVasPatch?.length > 0) {
      const answer = await CustomAlert({
        title: i18next.t('text.are_you_sure'),
        text: i18next.t('text.do_you_want_to_add_new_vas', { x: i18next.t('label.vas') }),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (!answer.value) return
    }

    const response = await client.mutate({
      mutation: gql`
        mutation updateMultipleOrderVas($orderNo: String!, $orderVasPatch: [OrderVasPatch!]!) {
          updateMultipleOrderVas(orderNo: $orderNo, patches: $orderVasPatch) {
            id
            name
          }
        }
      `,
      variables: { orderNo: this.orderNo, orderVasPatch: orderVasPatch }
    })

    if (!response.errors) {
      await this.fetchOrderVas()
      this.requestUpdate()
      this.showToast({ message: i18next.t('text.vas_successfully_updated') })
    }
  }

  getVasOrderPatch() {
    let orderVasPatch = []
    let hasError = false

    for (const [index, vas] of this.vasData.entries()) {
      const vasQtyInput = this.shadowRoot.getElementById(`vasQty-${index}`)
      const vasRemarkInput = this.shadowRoot.getElementById(`vasRemark-${index}`)

      const vasQty = vasQtyInput ? Number(vasQtyInput.value) : 0
      const vasRemark = vasRemarkInput ? vasRemarkInput.value : ''

      let cuFlag = '+'
      let patchId = null

      if (vas.orderVasId) {
        cuFlag = vasQty === vas.originalVasQty && vasRemark === vas.originalVasRemark ? 'N' : 'M'
        patchId = vas.orderVasId
      } else if (vasQty <= 0) {
        this.showToast({
          type: 'error',
          message: `The VAS quantity must be more than 0 for ${vas.name}`
        })
        hasError = true
        break
      }

      const patch = {
        bizplace: { id: this.bizplaceId },
        status: 'PROCESSING',
        orderVasItemsPatch: [
          {
            vas: { id: vas.vassId, name: vas.name },
            vasQty: vasQty,
            vasRemark: vasRemark,
            cuFlag: cuFlag
          }
        ],
        cuFlag: cuFlag
      }

      if (patchId) {
        patch.id = patchId
      }

      orderVasPatch.push(patch)
    }

    if (hasError) {
      return
    }

    return orderVasPatch.filter(patch => patch.cuFlag !== 'N')
  }

  handleRemoveVas(event) {
    const button = event.currentTarget
    const index = button.dataset.index
    const vas = this.vasData[index]

    if (vas && vas.orderVasId) {
      this.removeOrderVas(vas.orderVasId)
    } else {
      this.removeVas(index)
    }
  }

  removeVas(index) {
    this.vasData.splice(index, 1)
    this.requestUpdate()
  }

  async removeOrderVas(orderVasId) {
    const response = await client.mutate({
      mutation: gql`
        mutation deleteOrderVas($orderVasId: String!) {
          deleteOrderVas(id: $orderVasId)
        }
      `,
      variables: { orderVasId }
    })

    if (!response.errors) {
      await this.fetchOrderVas()
      this.requestUpdate()
      this.showToast({ message: i18next.t('text.vas_successfully_removed') })
    }
  }

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

window.customElements.define('add-vas-order-level', addVasOrderLevel)
