import '@things-factory/barcode-ui'
import '@things-factory/grist-ui'
import './check-inventory-popup'
import './relocate-inventory-popup'
import './add-extra-inventory-popup'

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

import { sleep } from '@operato/utils'
import { MultiColumnFormStyles } from '@things-factory/form-ui'
import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client, CustomAlert, PageView, store, UPDATE_CONTEXT } from '@things-factory/shell'
import { CommonButtonStyles } from '@things-factory/styles'

import { fetchLocationSortingRule } from '../../fetch-location-sorting-rule'
import { fetchSettingRule } from '../../fetch-setting-value'
import { LOCATION_SORTING_RULE, INVENTORY_CHECK_ITEM_STATUS } from '../constants'
import { showToast } from '../../util/index'

class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
  static get properties() {
    return {
      cycleCountId: String,
      cycleCountNo: String,
      locationName: String,
      cartonId: String,
      palletId: String,
      inventoryCheckItemStatus: String,
      locationFilter: Object,
      countNo: Number,
      isReleasing: Boolean,
      _hideCCColumnSetting: Boolean,
      _currentCard: Object,
      _incompleteInspection: Boolean,
      _editMode: Object,
      _editedCard: Object,
      _pageSettings: Object,
      _enableCartonLabel: Boolean,
      locationInfo: Array,
      bizplaceId: String,
      worksheetName: String,
      _ccCompleted: Boolean
    }
  }

  static get styles() {
    return [
      MultiColumnFormStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          overflow: auto;
          background-color: #22a6a7;
        }
        [product-card] {
          background: linear-gradient(rgb(243, 247, 251), 20%, rgb(255, 255, 255));
          box-shadow: var(--box-shadow);
          display: grid;
          gap: 5px 15px;
          clear: both;
          border-style: solid;
          border-width: thin;
          border-color: rgb(34, 166, 167);
          border-radius: var(--border-radius);
          padding: 5px;
          font-family: var(--subtitle-font);
          font-weight: bold;
          color: rgb(49, 90, 118);
          text-align: left;
        }
        [button-space] {
          margin: 5px;
          padding: var(--padding-narrow);
        }
        .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);
        }
        .white-color-button {
          --mdc-theme-primary: #f3f7fb;
          --mdc-theme-on-primary: #007f7e;
          --mdc-button-disabled-fill-color: #e0e0e0;
          --mdc-button-disabled-ink-color: #a6a4a2;
        }
        .card-header {
          margin-bottom: 0;
          padding-bottom: 0;
          text-align: center;
        }
        .card-text-bold {
          font-family: var(--subtitle-font);
          font-weight: bold;
          color: #315a76;
        }
        .missing-stock-notification {
          font-family: var(--subtitle-font);
          font-weight: bold;
          color: #dc4649;
        }
        data-grist {
          overflow: auto;
          flex: 1;
        }
        legend mwc-icon {
          vertical-align: middle;
          margin: var(--grist-title-icon-margin);
          font-size: var(--grist-title-icon-size);
          color: var(--grist-title-icon-color);
          cursor: pointer;
        }
        .content-container {
          background-color: #ffffff;
          height: 100%;
          text-align: center;
          border-radius: 5px;
          padding: 5px;
        }
        .content-header {
          margin: 5px;
          border-bottom: 1px solid rgb(34, 166, 167);
          font-weight: bold;
          font-size: large;
          color: rgb(49, 90, 118);
        }
        .hidden {
          display: none;
        }
        .input-font {
          font-weight: normal;
          font-size: 16px;
        }
      `
    ]
  }

  render() {
    return html`
      <!-- Cycle Count number field -->
      <div>
        <form id="info-form" class="multi-column-form">
          <label style="color: #ffffff;">${i18next.t('label.inventory_check_no')}</label>
          <barcode-scanable-input
            name="cycleCountNo"
            custom-input
            @keypress="${async e => {
              if (e.keyCode === 13) {
                e.preventDefault()
                if (this.cycleCountNoInput.value) {
                  this.clearView()
                  this.updateContext()
                  this.cycleCountNo = this.cycleCountNoInput.value
                  await this.fetchCycleCountWorksheet()
                }
              }
            }}"
          ></barcode-scanable-input>

          <!-- search fields -->
          <label style="color: #ffffff">${i18next.t('label.location')}</label>
          <barcode-scanable-input
            name="locationName"
            custom-input
            ?scan-only=${this._pageSettings?.cameraScanOnly}
            @keypress="${async e => {
              if (e.keyCode === 13) {
                e.preventDefault()
                if (this.locationNameInput?.value) {
                  this.clearView()
                  this.updateContext()
                  this.locationName = this.locationNameInput.value || null
                  this.cycleCountNo = this.cycleCountNoInput.value
                  this.fetchCycleCountWorksheet()
                } else if (!e.target.value) {
                  this.updateContext({
                    locationName: ''
                  })
                  this.locationName = ''
                  this.cycleCountNo = this.cycleCountNoInput.value
                  this.fetchCycleCountWorksheet()
                }
              }
            }}"
          ></barcode-scanable-input>

          <label style="color: #ffffff">${i18next.t('label.zone')}</label>
          <select
            name="zone"
            @change="${async e => {
              const zone = e.target.value
              if (zone === 'none') {
                delete this.locationFilter.zone
              } else {
                this.locationFilter.zone = zone
              }
              await this.fetchCycleCountWorksheet()
            }}"
          >
          <option value="none">-- Select Zone --</option>
          ${this.locationInfo?.zone?.map(itm => html` <option value=${itm}>${itm}</option> `)}
          </select>

          <label style="color: #ffffff">${i18next.t('label.row')}</label>
          <select
            name="row"
            @change="${async e => {
              const row = e.target.value
              if (row === 'none') {
                delete this.locationFilter.row
              } else {
                this.locationFilter.row = row
              }
              await this.fetchCycleCountWorksheet()
            }}"
          >
          <option value="none">-- Select Row --</option>
          ${this.locationInfo?.row.map(itm => html` <option value=${itm}>${itm}</option> `)}
          </select>
          <label style="color: #ffffff">${i18next.t('label.column')}</label>
          <select
            name="column"
            @change="${async e => {
              const column = e.target.value
              if (column === 'none') {
                delete this.locationFilter.column
              } else {
                this.locationFilter.column = column
              }
              await this.fetchCycleCountWorksheet()
            }}"
          >
          <option value="none">-- Select Column --</option>
          ${this.locationInfo?.column?.map(itm => html` <option value=${itm}>${itm}</option> `)}
          </select>

        <label style="color: #ffffff">${i18next.t('label.shelf')}</label>
          <select
            name="shelf"
            @change="${async e => {
              const shelf = e.target.value
              if (shelf === 'none') {
                delete this.locationFilter.shelf
              } else {
                this.locationFilter.shelf = shelf
              }
              await this.fetchCycleCountWorksheet()
            }}"
          >
          <option value="none">-- Select Shelf --</option>
          ${this.locationInfo?.shelf?.map(itm => html`<option value=${itm}>${itm}</option>`)}

          </select>
          ${
            this._enableCartonLabel
              ? html`
                  <label style="color: #ffffff">${i18next.t('label.carton_id')}</label>
                  <barcode-scanable-input
                    name="cartonId"
                    custom-input
                    ?scan-only=${this._pageSettings?.cameraScanOnly}
                    @keypress="${async e => {
                      if (e.keyCode === 13) {
                        e.preventDefault()
                        if (this.cartonIdInput?.value) {
                          this.clearView()
                          this.updateContext()
                          this.cartonId = this.cartonIdInput.value || null
                          this.cycleCountNo = this.cycleCountNoInput?.value
                          this.fetchCycleCountWorksheet()
                        } else if (!e.target.value) {
                          this.updateContext({
                            cartonId: ''
                          })
                          this.cartonId = ''
                          this.cycleCountNo = this.cycleCountNoInput.value
                          this.fetchCycleCountWorksheet()
                        }
                      }
                    }}"
                  ></barcode-scanable-input>
                `
              : html`
                  <label style="color: #ffffff">${i18next.t('label.lot_id')}</label>
                  <barcode-scanable-input
                    name="palletId"
                    custom-input
                    ?scan-only=${this._pageSettings?.cameraScanOnly}
                    @keypress="${async e => {
                      if (e.keyCode === 13) {
                        e.preventDefault()
                        if (this.palletIdInput?.value) {
                          this.clearView()
                          this.updateContext()
                          this.palletId = this.palletIdInput.value || null
                          this.cycleCountNo = this.cycleCountNoInput.value
                          this.fetchCycleCountWorksheet()
                        } else if (!e.target.value) {
                          this.updateContext({
                            palletId: ''
                          })
                          this.palletId = ''
                          this.cycleCountNo = this.cycleCountNoInput.value
                          this.fetchCycleCountWorksheet()
                        }
                      }
                    }}"
                  ></barcode-scanable-input>
                `
          }
          <label style="color: #ffffff">${i18next.t('label.product_info')}</label>
              <barcode-scanable-input
                name="productInfo"
                custom-input
                ?scan-only=${this._pageSettings?.cameraScanOnly}
                @keypress="${async e => {
                  if (e.keyCode === 13) {
                    e.preventDefault()
                    if (this.productInfoInput?.value) {
                      this.clearView()
                      this.updateContext()
                      this.productInfo = this.productInfoInput.value || null
                      this.cycleCountNo = this.cycleCountNoInput.value
                      this.fetchCycleCountWorksheet()
                    } else if (!e.target.value) {
                      this.updateContext({
                        productInfo: null
                      })
                      this.productInfo = null
                      this.cycleCountNo = this.cycleCountNoInput.value
                      this.fetchCycleCountWorksheet()
                    }
                  }
                }}"
              ></barcode-scanable-input>
          <label style="color: #ffffff">${i18next.t('label.status')}</label>
          <select
            name="inventoryCheckItemStatus"
            @change="${async e => {
              this.inventoryCheckItemStatus = e.target.value
              this._arrayIndex = 0
              await this.fetchCycleCountWorksheet()
            }}"
          >
            <option value="" ?selected="${this.inventoryCheckItemStatus === ''}">Please select a status</option>
            <option value="INSPECTED" ?selected="${this.inventoryCheckItemStatus === 'INSPECTED'}">Inspected</option>
            <option value="RELOCATED" ?selected="${this.inventoryCheckItemStatus === 'RELOCATED'}">Relocated</option>
            <option value="ADDED" ?selected="${this.inventoryCheckItemStatus === 'ADDED'}">Added</option>
            <option value="INSPECTING" ?selected="${this.inventoryCheckItemStatus === 'INSPECTING'}">Inspecting</option>
            <option value="MISSING" ?selected="${this.inventoryCheckItemStatus === 'MISSING'}">Missing</option>
            <option value="NOT_TALLY" ?selected="${this.inventoryCheckItemStatus === 'NOT_TALLY'}">Not Tally</option>
          </select>


        </form>
      </div>

      <!-- Inventory Check title for product card -->
      <div class="content-container">
        <div class="content-header" >
          <label>
            ${`${i18next.t('title.inventory_check_no')}${`: ${this.cycleCountNo ? this.cycleCountNo : ''}`}`}
          </label>
        </div>
        <div>
          <!--checked inventory-->
          <label class="card-header">
            <font class="card-text-bold"
            >${i18next.t('label.checked_inventory')}
            ${this._currentCard.checkedInventoryCount || '0'}/${this._currentCard.totalItems || '0'}</font>
          </label><br/>
            <!--checkbox -->
          <label class="card-header">
            ${
              this._currentCard.checked
                ? html`<input type="checkbox" disabled="disabled" checked /><br />`
                : html`<input type="checkbox" disabled="disabled" /><br />`
            }
          </label>
        </div>
          <!-- product-card -->
          <div product-card id="form">
            <form id="input-form" class="single-column-form">
                  <label>${i18next.t('label.location')}</label><br />
                  <!-- fetch inspected location first. If an invetories location is changed, it will fetch the new location. -->
                  <label class="input-font">${
                    this._currentCard.inspectedLocation || this._currentCard.originLocation
                  }</label><br />
                  <!-- validation lot id, carton id -->
                  ${
                    this._enableCartonLabel
                      ? html` <label>${i18next.t('label.carton_id')}</label>
                          <br /><label class="input-font">${this._currentCard.cartonId}</label>`
                      : html` <label>${i18next.t('label.lot_id')}</label>
                          <br /><label class="input-font">${this._currentCard.palletId}</label>`
                  }
                  <br />
                  <label>${i18next.t('label.sku')}</label>
                  <br />
                  <label class="input-font">${this._currentCard.productSku}</label>
                  <br />
                  <label>${i18next.t('label.product')}</label>
                  <br />
                  <label class="input-font">${this._currentCard.productName}</label>
                  <br />
                  <label>${i18next.t('label.packing_type')}</label>
                  <br />
                  <label class="input-font">${this._currentCard.packingType}</label>
                  <br />
                  <label>${i18next.t('label.release_qty')}</label>
                  <br />
                  <label class="input-font">${this._currentCard.lockedQty}</label>
                  <br />
                  <label>${i18next.t('label.status')}</label>
                  <br />
                  <label class="input-font">${this._currentCard.inventoryCheckItemStatus}</label>
                  <br />
                  <label>${i18next.t('label.uom')}</label>
                  <br />
                  <label class="input-font">${this._currentCard.uom}</label>
                  <br />
                  ${
                    this._currentCard.inventoryCheckItemStatus == 'RELOCATED' ||
                    this._currentCard.inventoryCheckItemStatus == 'ADDED'
                      ? html`
                          <label>${`${i18next.t('label.inspected_location')}: `}</label>
                          <br />
                          <label class="input-font">${this._currentCard.inspectedLocation}</label>
                          <br />
                        `
                      : ''
                  }
                  <label>${i18next.t('label.inspected_batch_no')}
                  </label>
                  <br />
                  <span class="input-font" ?hidden=${this._editMode.inspectedBatchNo}>${
      this._currentCard.inspectedBatchNo
        ? this._currentCard.inspectedBatchNo
        : this._hideCCColumnSetting && !this._enableCartonLabel
        ? ''
        : this._currentCard.originBatchNo
    }
                      <mwc-icon-button
                        icon="edit"
                        align="end"
                        @click=${() => this._enableEditMode('inspectedBatchNo')}
                      ></mwc-icon-button>
                    </span>
                    <span ?hidden=${!this._editMode.inspectedBatchNo}>
                      <input
                        type="text"
                        .value=${this._editedCard.inspectedBatchNo || this._currentCard.originBatchNo}
                        @input=${e => this._handleEditInput('inspectedBatchNo', e.target.value)}
                      />
                      <mwc-icon-button icon="save" @click=${() => this._saveEdit('inspectedBatchNo')}></mwc-icon-button>
                      <mwc-icon-button
                        icon="cancel"
                        @click=${() => {
                          this._editedCard.inspectedBatchNo = this._currentCard.originBatchNo
                          this._disableEditMode('inspectedBatchNo')
                        }}
                      ></mwc-icon-button>
                    </span>
                  <br />
                  <label>${i18next.t('label.inspected_expiration_date')}
                  </label>
                  <br />
                  <span class="input-font" ?hidden=${this._editMode.inspectedExpirationDate}>
                      ${this._currentCard.inspectedExpirationDate}
                      <mwc-icon-button
                        icon="edit"
                        align="end"
                        @click=${() => this._enableEditMode('inspectedExpirationDate')}
                      ></mwc-icon-button>
                    </span>
                    <span ?hidden=${!this._editMode.inspectedExpirationDate}>
                      <input type="date"
                        .value=${
                          this._editedCard?.inspectedExpirationDate
                            ? this._editedCard?.inspectedExpirationDate
                            : this._hideCCColumnSetting
                            ? ''
                            : this._currentCard.originExpirationDate
                        }
                        @input=${e => this._handleEditInput('inspectedExpirationDate', e.target.value)}
                      />
                      <mwc-icon-button icon="save" @click=${() =>
                        this._saveEdit('inspectedExpirationDate')}></mwc-icon-button>
                      <mwc-icon-button
                        icon="cancel"
                        @click=${() => this._disableEditMode('inspectedExpirationDate')}
                      ></mwc-icon-button>
                    </span>
                  <br />
                  <label>${i18next.t('label.inspected_qty')}
                  </label>
                  <br />
                  <span class="input-font" ?hidden=${this._editMode.inspectedQty}>
                      ${this._currentCard.inspectedQty}
                      <mwc-icon-button
                        icon="edit"
                        align="end"
                        @click=${() => this._enableEditMode('inspectedQty')}
                      ></mwc-icon-button>
                    </span>
                    <span ?hidden=${!this._editMode.inspectedQty}>
                      <input type="text"
                        .value=${
                          this._editedCard?.inspectedQty
                            ? this._editedCard?.inspectedQty
                            : this._hideCCColumnSetting
                            ? ''
                            : this._currentCard.originQty
                        }
                        @input=${e => this._handleEditInput('inspectedQty', e.target.value)}
                      />
                      <mwc-icon-button icon="save" @click=${() => this._saveEdit('inspectedQty')}></mwc-icon-button>
                      <mwc-icon-button
                        icon="cancel"
                        @click=${() => this._disableEditMode('inspectedQty')}
                      ></mwc-icon-button>
                    </span>
                  <br />
                  ${
                    !this._enableCartonLabel
                      ? html`
                          <label>${i18next.t('label.inspected_uom_value')}</label>
                          <br />
                          <span class="input-font" ?hidden=${this._editMode.inspectedUomValue}>
                            ${this._currentCard.inspectedUomValue}
                            <mwc-icon-button
                              icon="edit"
                              align="end"
                              @click=${() => this._enableEditMode('inspectedUomValue')}
                            ></mwc-icon-button>
                          </span>
                          <span ?hidden=${!this._editMode.inspectedUomValue}>
                            <input
                              class="input-font"
                              type="text"
                              .value=${this._editedCard?.inspectedUomValue
                                ? this._editedCard?.inspectedUomValue
                                : this._hideCCColumnSetting
                                ? ''
                                : this._currentCard.originUomValue}
                              @input=${e => this._handleEditInput('inspectedUomValue', e.target.value)}
                            />
                            <mwc-icon-button
                              icon="save"
                              @click=${() => this._saveEdit('inspectedUomValue')}
                            ></mwc-icon-button>
                            <mwc-icon-button
                              icon="cancel"
                              @click=${() => this._disableEditMode('inspectedUomValue')}
                            ></mwc-icon-button>
                          </span>
                        `
                      : ''
                  }
            </form>
          </div>
          <div button-space>
            <mwc-button
              @click=${e => this.previousCard(e)}
              ?disabled=${this._disablePrevious}
              raised
              label="<"
            ></mwc-button>
            <span>${this._currentCard.currentPage || '0'}/${this._currentCard.totalPages || '0'}</span>
            <mwc-button @click=${e => this.nextCard(e)} ?disabled=${this._disableNext} raised label=">"></mwc-button>
          </div>
        </div>
      </div>
    `
  }

  constructor() {
    super()
    this.isReleasing = false
    this.locationSortingRules = []
    this._hideCCColumnSetting = false
    this._selectedInventoryCheckItem = null
    this.locationFilter
    this.data = { records: [] }
    this._enableCartonLabel = false
    this._currentCard = {
      checkedInventoryCount: 0
    }
    this._editMode = {
      inspectedBatchNo: false,
      inspectedQty: false,
      inspectedUomValue: false,
      inspectedExpirationDate: false
    }
    this._editedCard = {}
    this._arrayIndex = 0
    this.itemsPerPage = 1
    this.totalItems = 0
    this.totalPages = Math.ceil(this.totalItems / this.itemsPerPage)
    this.currentPage = Math.floor(this._arrayIndex / this.itemsPerPage) + 1
    this._incompleteInspection = true
    this._ccCompleted = false
  }

  get context() {
    return {
      title: i18next.t('title.inventory_inspection'),
      help: 'operato-wms/inventory-check/inspecting-product'
    }
  }

  get infoForm() {
    return this.renderRoot.querySelector('form#info-form')
  }

  get inputForm() {
    return this.renderRoot.querySelector('form#input-form')
  }

  get cycleCountNoInput() {
    return this.renderRoot.querySelector('barcode-scanable-input[name=cycleCountNo]').renderRoot.querySelector('input')
  }

  get locationNameInput() {
    return this.renderRoot.querySelector('barcode-scanable-input[name=locationName]')?.renderRoot.querySelector('input')
  }

  get cartonIdInput() {
    return this.renderRoot.querySelector('barcode-scanable-input[name=cartonId]')?.renderRoot.querySelector('input')
  }

  get palletIdInput() {
    return this.renderRoot.querySelector('barcode-scanable-input[name=palletId]')?.renderRoot.querySelector('input')
  }

  get palletIdInput() {
    return this.renderRoot.querySelector('barcode-scanable-input[name=palletId]')?.renderRoot.querySelector('input')
  }

  get productInfoInput() {
    return this.renderRoot.querySelector('barcode-scanable-input[name=productInfo]')?.renderRoot.querySelector('input')
  }

  get inspectedBatchNoInput() {
    return this.renderRoot.querySelector('input[name=inspectedBatchNo]')
  }

  get bizplaceNameInput() {
    return this.renderRoot.querySelector('input[name=bizplace]')
  }

  get inspectedQtyInput() {
    return this.renderRoot.querySelector('input[name=inspectedQty]')
  }

  get inspectedUomValueInput() {
    return this.renderRoot.querySelector('input[name=inspectedUomValue]')
  }

  selectOnInput(input) {
    setTimeout(() => input.select(), 100)
  }

  async pageInitialized() {
    const [locationSortingTask, cameraScanOnly, enableCarton] = [
      fetchLocationSortingRule(LOCATION_SORTING_RULE.INSPECTING_PRODUCT.value),
      fetchSettingRule('camera-scan-only'),
      fetchSettingRule('enable-carton-label')
    ]

    this.locationSortingRules = await locationSortingTask

    this._pageSettings = {
      ...this._pageSettings,
      cameraScanOnly: (await cameraScanOnly) || false,
      enableCarton: (await enableCarton) || false
    }

    this.updateContext()
  }

  pageUpdated() {
    if (this.active) {
      if (this.cycleCountNo) {
        if (this._arrayIndex < this.data.records.length) {
          this._disableNext = false
          this._disablePrevious = false
          if (this.data.records.length - 1 == this._arrayIndex) {
            this._disableNext = true
            this._disablePrevious = false
          }
        }
        if (this._arrayIndex == 0) {
          this._disablePrevious = true
          this._disableNext = false
        }
        if (this.data.records.length == 1) {
          this._disableNext = true
          this._disablePrevious = true
        }
        this.selectOnInput(this.cycleCountNoInput)

        this._currentCard = this.data.records[this._arrayIndex] ? this.data.records[this._arrayIndex] : {}

        const currentStatus = this._currentCard.wsdStatus
        this._incompleteInspection = currentStatus !== 'INSPECTED' && currentStatus !== 'NOT TALLY'
        this.updateCurrentCard()

        this.calculateCheckedInventoryCount()
        this.updateContext()
      }
    }
  }

  async fetchCycleCountWorksheet() {
    try {
      const isCartonEnabled = this._pageSettings?.enableCarton
      const worksheetQuery = isCartonEnabled ? 'cycleCountWorksheetForCarton' : 'cycleCountWorksheetForPallet'

      const response = await client.query({
        query: gql`
        query ${worksheetQuery}($inventoryCheckNo: String!, $locationSortingRules: [Sorting], $locationName: String, $cartonId: String, $palletId: String, $productInfo: String,$inventoryCheckItemStatus: String, $locationFilter : LocationFilter) {
          ${worksheetQuery}(
            inventoryCheckNo: $inventoryCheckNo
            locationSortingRules: $locationSortingRules
            locationName: $locationName
            cartonId: $cartonId
            palletId: $palletId
            productInfo: $productInfo
            inventoryCheckItemStatus: $inventoryCheckItemStatus
            locationFilter : $locationFilter
          ) {
            worksheetInfo {
              inventoryCheck{
                id
              }
              name
              status
              startedAt
              bizplace {
                id
                name
                description
              }
              partnerDomainId
              ccCompleted
            }
            worksheetDetailInfos {
              name
              cartonId
              palletId
              batchId
              qty
              packingType
              uomValue
              uom
              status
              originLocation {
                id
                name
              }
              originQty
              originUomValue
              originExpirationDate
              inspectedBatchNo
              inspectedQty
              inspectedUomValue
              inspectedExpirationDate
              inspectedLocation {
                id
                name
                warehouse {
                  name
                }
                zone
                column
                row
              }
              product {
                id
                sku
                name
                description
                isInventoryDecimal
              }
              productDetail {
                id
              }
              description
              location {
                id
                name
                warehouse {
                  name
                }
                zone
                column
                row
                shelf
              }
              relatedInvCheckItem {
                originBatchNo
                inventory {
                  id
                  lockedQty
                }
                status
                countNo
              }
            }
          }
        }
        `,
        variables: {
          inventoryCheckNo: this.cycleCountNo,
          locationSortingRules: this.locationSortingRules,
          locationName: this.locationName,
          cartonId: this.cartonId,
          palletId: this.palletId,
          productInfo: this.productInfo,
          inventoryCheckItemStatus: this.inventoryCheckItemStatus,
          locationFilter: this.locationFilter
        }
      })

      if (!response.errors) {
        const worksheetData = response.data[worksheetQuery]
        const { worksheetInfo, worksheetDetailInfos } = worksheetData
        const partnerDomainId = worksheetInfo.partnerDomainId
        this.worksheetName = worksheetInfo.name
        this.bizplaceName = worksheetInfo.bizplace.name
        this.bizplaceId = worksheetInfo.bizplace.id
        this.worksheetStatus = worksheetInfo.status
        this._ccCompleted = worksheetInfo.ccCompleted
        this.cycleCountId = worksheetInfo.inventoryCheck.id
        let mappedLocationInfo = data => {
          const location = data.reduce(
            (tot, itm) => {
              tot.zone.add(itm.zone), tot.column.add(itm.column), tot.row.add(itm.row), tot.shelf.add(itm.shelf)
              return tot
            },
            {
              zone: new Set(),
              column: new Set(),
              row: new Set(),
              shelf: new Set()
            }
          )

          location.zone = Array.from(location.zone)
          location.column = Array.from(location.column)
          location.row = Array.from(location.row)
          location.shelf = Array.from(location.shelf)

          return location
        }
        this.locationInfo = mappedLocationInfo(worksheetDetailInfos.map(item => item.location))

        // Fetch settings in parallel
        const [enableCartonLabel, hideCCColumnSetting] = await Promise.all([
          fetchSettingRule('enable-carton-label', partnerDomainId),
          fetchSettingRule('hide-cc-columns', partnerDomainId)
        ])

        this._enableCartonLabel = enableCartonLabel
        this._hideCCColumnSetting = hideCCColumnSetting

        if (isCartonEnabled) {
          const groupedRecords = worksheetDetailInfos.reduce((acc, item) => {
            const key = `${item.productDetail.id}-${item.cartonId}-${item.batchId}-${item.location.name}`
            if (!acc[key])
              acc[key] = {
                items: [],
                totalOriginQty: 0,
                totalInspectedQty: 0,
                totalLockedQty: 0
              }
            acc[key].items.push(item)
            acc[key].totalInspectedQty += item.inspectedQty
            acc[key].totalOriginQty += item.qty
            acc[key].totalLockedQty += item.relatedInvCheckItem?.inventory?.lockedQty || 0
            return acc
          }, {})

          const totalItems = Object.keys(groupedRecords).length
          const itemsPerPage = 1
          const totalPages = Math.ceil(totalItems / itemsPerPage)

          this.data.records = Object.values(groupedRecords).map((groupObj, index) => {
            const group = groupObj.items
            const { inspectedQty, lockedQty, ...worksheetDetails } = this.mapWorksheetDetails(group[0])

            return {
              qty: group.reduce((sum, item) => sum + item.qty, 0),
              inspectedQty: groupObj.totalInspectedQty
                ? groupObj.totalInspectedQty
                : this._hideCCColumnSetting
                ? null
                : groupObj.totalOriginQty,
              lockedQty: groupObj.totalLockedQty,
              ...worksheetDetails,
              totalItems: totalItems,
              itemsPerPage: itemsPerPage,
              totalPages: totalPages,
              currentPage: index + 1
            }
          })
        } else {
          this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
        }

        this.fillUpForm(this.infoForm, worksheetInfo)
        this._arrayIndex =
          this._arrayIndex < this.formatWorksheetDetailInfos(worksheetDetailInfos).length ? this._arrayIndex : 0
        this._currentCard = this.data.records[this._arrayIndex]
        this.updateCurrentCard()
        this.missingInventoryData = { records: this.formatMissingInventories(worksheetDetailInfos) }
        this.calculateCheckedInventoryCount()
        this.updateNavigationButtons(worksheetDetailInfos.length, this._arrayIndex)

        this.updateContext()
      }
    } catch (error) {
      showToast(error)
    }
  }

  updateNavigationButtons(total, index) {
    this._disableNext = total - 1 === index || total === 1
    this._disablePrevious = index === 0 || total === 1
  }

  mapWorksheetDetails(record) {
    const {
      name,
      product,
      productDetail,
      originLocation,
      originQty,
      originUomValue,
      originExpirationDate,
      inspectedQty,
      inspectedBatchNo,
      inspectedUomValue,
      inspectedExpirationDate,
      inspectedLocation,
      relatedInvCheckItem,
      status,
      location
    } = record

    return {
      ...record,
      worksheetDetailName: name,
      productName: product?.name || '',
      productSku: product?.sku || '',
      productDetailId: productDetail?.id || '',
      originLocation: originLocation?.name || null,
      inspectedBatchNo: inspectedBatchNo || '',
      inspectedUomValue: inspectedUomValue ? inspectedUomValue : this._hideCCColumnSetting ? null : originUomValue,
      inspectedQty: inspectedQty ? inspectedQty : this._hideCCColumnSetting ? null : originQty,
      inspectedExpirationDate: inspectedExpirationDate
        ? inspectedExpirationDate
        : this._hideCCColumnSetting
        ? null
        : !inspectedUomValue && !inspectedQty //to handle if inspectedExpirationDate is null
        ? originExpirationDate
        : inspectedExpirationDate,
      inspectedLocation: inspectedLocation?.name || null,
      inventoryCheckItemStatus: relatedInvCheckItem?.status,
      countNo: relatedInvCheckItem?.countNo,
      locationId: location?.id,
      locationName: location?.name || '',
      wsdStatus: status,
      lockedQty: relatedInvCheckItem?.inventory?.lockedQty || 0,
      originBatchNo:
        this._hideCCColumnSetting && !this._enableCartonLabel ? null : relatedInvCheckItem?.originBatchNo || null
    }
  }

  formatWorksheetDetailInfos(wsdInfos) {
    const totalItems = wsdInfos.length
    const itemsPerPage = 1
    const totalPages = Math.ceil(totalItems / itemsPerPage)

    return wsdInfos.map((record, index) => {
      return {
        ...this.mapWorksheetDetails(record),
        totalItems: totalItems,
        itemsPerPage: itemsPerPage,
        totalPages: totalPages,
        currentPage: Math.floor(index / itemsPerPage) + 1
      }
    })
  }

  formatMissingInventories(wsdInfos) {
    return wsdInfos
      .filter(wsdInfo => wsdInfo.relatedInvCheckItem.status === INVENTORY_CHECK_ITEM_STATUS.MISSING.value)
      .map(record => this.mapWorksheetDetails(record))
  }

  async submitInventoryCheck() {
    try {
      await this.checkInputFormValidity()

      let currentCard = { ...this._currentCard }

      if (!currentCard.inspectedBatchNo) {
        currentCard.inspectedBatchNo = currentCard.originBatchNo
      }

      const {
        name,
        inspectedQty: rawInspectedQty,
        inspectedUomValue: rawInspectedUomValue,
        inspectedExpirationDate,
        cartonId,
        palletId,
        productDetailId,
        batchId,
        locationId
      } = currentCard

      const inspectedQty = Number(rawInspectedQty)
      let inspectedUomValue = Number(rawInspectedUomValue)

      if (cartonId && palletId) {
        inspectedUomValue = inspectedQty
      }

      const variables = {
        inspectedBatchNo: currentCard.inspectedBatchNo,
        inspectedQty,
        inspectedExpirationDate: inspectedExpirationDate == '' ? null : inspectedExpirationDate,
        inspectedUomValue
      }

      let response

      if (!this._enableCartonLabel) {
        // Mutate for inspecting pallet
        Object.assign(variables, { worksheetDetailName: name })
        response = await client.mutate({
          mutation: gql`
            mutation inspectingPallet(
              $worksheetDetailName: String!
              $inspectedBatchNo: String!
              $inspectedQty: Float!
              $inspectedUomValue: Float!
              $inspectedExpirationDate: Date
            ) {
              inspectingPallet(
                worksheetDetailName: $worksheetDetailName
                inspectedBatchNo: $inspectedBatchNo
                inspectedQty: $inspectedQty
                inspectedUomValue: $inspectedUomValue
                inspectedExpirationDate: $inspectedExpirationDate
              )
            }
          `,
          variables: variables
        })
      } else {
        // Mutate for inspecting carton
        Object.assign(variables, {
          productDetailId,
          cartonId,
          batchId,
          locationId
        })
        response = await client.mutate({
          mutation: gql`
            mutation inspectingCarton(
              $productDetailId: String!
              $cartonId: String!
              $batchId: String!
              $locationId: String!
              $inspectedBatchNo: String!
              $inspectedQty: Float!
              $inspectedUomValue: Float!
              $inspectedExpirationDate: Date
            ) {
              inspectingCarton(
                productDetailId: $productDetailId
                cartonId: $cartonId
                batchId: $batchId
                locationId: $locationId
                inspectedBatchNo: $inspectedBatchNo
                inspectedQty: $inspectedQty
                inspectedUomValue: $inspectedUomValue
                inspectedExpirationDate: $inspectedExpirationDate
              )
            }
          `,
          variables: variables
        })
      }

      if (!response.errors) {
        await this.fetchCycleCountWorksheet()
        this.pageUpdated()
        this.showToast({ message: i18next.t('text.the_inventory_has_been_successfully_checked') })
      }
    } catch (e) {
      this.showToast(e)
    }
  }

  updateContext() {
    let actions = []

    // Check if all cards have a status of 'NOT_TALLY' or 'DONE'
    if (this.data.records.length > 0 && this.data.records) {
      if (this._ccCompleted) {
        actions.push({
          title: i18next.t('button.complete'),
          action: this.completeCycleCount.bind(this),
          ...CommonButtonStyles.submit
        })
      }

      if (this.worksheetStatus == 'EXECUTING') {
        const status = this._currentCard.inventoryCheckItemStatus
        if (['MISSING', 'RELOCATED', 'INSPECTED', 'NOT_TALLY'].includes(status)) {
          actions.push({
            title: i18next.t('button.undo'),
            action: this.undoInventoryCheck.bind(this),
            ...CommonButtonStyles.undo
          })
        } else if (status !== 'ADDED') {
          actions.push({
            title: i18next.t('button.check'),
            action: this.submitInventoryCheck.bind(this),
            ...CommonButtonStyles.submit
          })

          actions.push({
            title: i18next.t('button.check_missing_x', { state: { x: i18next.t('label.inventory') } }),
            action: this.checkMissingInventory.bind(this),
            ...CommonButtonStyles.confirm
          })
        }

        if (!['RELOCATED', 'INSPECTED', 'NOT_TALLY', 'ADDED', 'MISSING'].includes(status)) {
          actions.push({
            title: i18next.t('button.relocate'),
            action: this.relocateInventory.bind(this),
            ...CommonButtonStyles.relocate
          })
        }

        actions.push({
          title: i18next.t('button.check_unknown_inventory'),
          action: this.checkUnknownInventory.bind(this),
          ...CommonButtonStyles.confirm
        })

        actions.push({
          title: i18next.t('button.add_x', { state: { x: i18next.t('label.inventory') } }),
          action: this.addExtraInventory.bind(this),
          ...CommonButtonStyles.additional
        })
      }
    }
    store.dispatch({
      type: UPDATE_CONTEXT,
      context: {
        ...this.context,
        actions
      }
    })
  }

  fillUpForm(form, data) {
    form.reset()
    //prevent form from reseting the values of the location filter
    if (Object.keys(this.locationFilter).length > 0) {
      Object.entries(this.locationFilter).forEach(([key, value]) => {
        form.elements[key].value = value
      })
    }
    for (let key in data) {
      Array.from(form.querySelectorAll('input')).forEach(field => {
        if (field.name === key && field.type === 'checkbox') {
          field.checked = data[key]
        } else if (field.name === key && field.type === 'datetime-local') {
          const datetime = Number(data[key])
          const timezoneOffset = new Date(datetime).getTimezoneOffset() * 60000
          field.value = new Date(datetime - timezoneOffset).toISOString().slice(0, -1)
        } else if (field.name === key) {
          if (data[key] instanceof Object) {
            const objectData = data[key]
            field.value = `${objectData.name}`
          } else {
            field.value = data[key]
          }
        }
      })
    }
  }

  async checkInputFormValidity() {
    let { inspectedBatchNo, inspectedQty, inspectedUomValue, inspectedExpirationDate, cartonId, palletId } =
      this._currentCard
    inspectedQty = Number(inspectedQty)

    // Check if inspectedQty has more than 3 decimal places
    const decimalPlaces = inspectedQty.toString().split('.')[1]?.length || 0
    if (decimalPlaces > 3) {
      throw new Error(i18next.t('text.maximum_3_decimal_places_allowed'))
    }

    // If the currentCard has both a cartonId and a palletId, set inspectedUomValue to be the same as inspectedQty
    if (cartonId && palletId) {
      inspectedUomValue = inspectedQty
    } else {
      inspectedUomValue = Number(inspectedUomValue)
    }

    if (!inspectedBatchNo) {
      inspectedBatchNo = this._currentCard.originBatchNo
    }

    if (!inspectedBatchNo) {
      throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('field.inspected_batch_no') } }))
    }

    if (!inspectedQty) {
      throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('field.inspected_qty') } }))
    }

    // Check if quantity has decimals and validate against product settings
    if (inspectedQty % 1 !== 0 && !this._currentCard.product?.isInventoryDecimal) {
      throw new Error(i18next.t('text.decimal_quantities_not_allowed'))
    }

    if (inspectedExpirationDate) {
      let getYear = parseInt(inspectedExpirationDate?.slice(0, 4))

      if (getYear > 9999) {
        throw new Error(i18next.t('text.please_enter_the_correct_date_format'))
      }
    }

    if (inspectedQty <= 0) {
      throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('field.inspected_qty') } }))
    }

    if (!this._enableCartonLabel) {
      if (!inspectedUomValue) {
        throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('field.inspected_uom_value') } }))
      }

      if (inspectedUomValue <= 0) {
        throw new Error(
          i18next.t('text.x_should_be_positive', { state: { x: i18next.t('field.inspected_uom_value') } })
        )
      }
    }
  }

  async undoInventoryCheck() {
    await sleep(1010)
    try {
      const { name, cartonId, productDetailId, batchId, locationId, countNo } = this._currentCard

      const result = await CustomAlert({
        title: i18next.t('title.are_you_sure'),
        text: i18next.t('text.undo_inspection'),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (result.value) {
        let response

        if (!this._enableCartonLabel) {
          response = await client.mutate({
            mutation: gql`
              mutation undoInspection($worksheetDetailName: String!) {
                undoInspection(worksheetDetailName: $worksheetDetailName)
              }
            `,
            variables: { worksheetDetailName: name }
          })
        } else {
          response = await client.mutate({
            mutation: gql`
              mutation undoInspectionCarton(
                $productDetailId: String!
                $cartonId: String!
                $batchId: String!
                $locationId: String!
                $inventoryCheckNo: String!
                $countNo: Int!
              ) {
                undoInspectionCarton(
                  productDetailId: $productDetailId
                  cartonId: $cartonId
                  batchId: $batchId
                  locationId: $locationId
                  inventoryCheckNo: $inventoryCheckNo
                  countNo: $countNo
                )
              }
            `,
            variables: {
              productDetailId,
              cartonId,
              batchId,
              locationId,
              inventoryCheckNo: this.cycleCountNo,
              countNo
            }
          })
        }

        if (!response.errors) {
          await this.fetchCycleCountWorksheet()
          this.resetInput()
          this.showToast({ message: i18next.t('text.the_inventory_has_been_successfully_reverted') })
        }
      }
    } catch (e) {
      this.showToast(e)
    }
  }

  async checkMissingInventory() {
    await sleep(1010)
    try {
      const { name, cartonId, productDetailId, batchId, locationId } = this._currentCard

      const result = await CustomAlert({
        title: i18next.t('title.are_you_sure'),
        text: i18next.t('button.check_missing_x', { state: { x: i18next.t('field.inventory') } }),
        confirmButton: { text: i18next.t('button.confirm') },
        cancelButton: { text: i18next.t('button.cancel') }
      })

      if (!result.value) {
        return
      }

      let response

      if (!this._enableCartonLabel) {
        response = await client.mutate({
          mutation: gql`
            mutation checkMissingInventory($worksheetDetailName: String!) {
              checkMissingInventory(worksheetDetailName: $worksheetDetailName)
            }
          `,
          variables: { worksheetDetailName: name }
        })
      } else {
        response = await client.mutate({
          mutation: gql`
            mutation checkMissingInventoryCarton(
              $productDetailId: String!
              $cartonId: String!
              $batchId: String!
              $locationId: String!
              $inventoryCheckId: String!
            ) {
              checkMissingInventoryCarton(
                productDetailId: $productDetailId
                cartonId: $cartonId
                batchId: $batchId
                locationId: $locationId
                inventoryCheckId: $inventoryCheckId
              )
            }
          `,
          variables: { productDetailId, cartonId, batchId, locationId, inventoryCheckId: this.cycleCountId }
        })
      }

      if (!response.errors) {
        await this.fetchCycleCountWorksheet()
        this.showToast({ message: i18next.t('text.the_inventory_has_been_marked_as_missing') })
      }
    } catch (e) {
      this.showToast(e)
    }
  }

  async checkUnknownInventory() {
    await sleep(1010)
    openPopup(
      html`
        <check-inventory-popup
          .worksheetName="${this.worksheetName}"
          .cycleCountNo="${this.cycleCountNo}"
          .bizplaceId="${this.bizplaceId}"
          .missingInventory="${this.missingInventoryData}"
          .enableCartonLabel="${this._enableCartonLabel}"
        ></check-inventory-popup>
      `,
      {
        backdrop: true,
        size: 'medium',
        title: i18next.t('title.check_unknown_inventory')
      }
    )
  }

  async addExtraInventory() {
    await sleep(1010)
    try {
      openPopup(
        html`
          <add-extra-inventory-popup
            .bizplaceId="${this.bizplaceId}"
            .bizplaceName="${this.bizplaceName}"
            .cycleCountNo="${this.cycleCountNo}"
            .countNo="${this._currentCard.countNo}"
            .enableCartonLabel="${this._enableCartonLabel}"
            @add-inventory="${async e => {
              history.back()
              await this.fetchCycleCountWorksheet()
              this.pageUpdated()
              this.updateContext()
            }}"
          ></add-extra-inventory-popup>
        `,
        {
          backdrop: true,
          size: 'medium',
          title: i18next.t('title.add_inventory')
        }
      )
    } catch (e) {
      this.showToast(e)
    }
  }

  async relocateInventory() {
    try {
      await sleep(1010)
      await this.checkInputFormValidity()

      let currentCards = { ...this._currentCard }

      if (!currentCards.inspectedBatchNo) {
        currentCards.inspectedBatchNo = currentCards.originBatchNo
      }

      let { inspectedQty, inspectedUomValue, cartonId, palletId } = currentCards

      // If the currentCard has both cartonId & palletId, set inspectedUomValue to be the same as inspectedQty
      inspectedQty = Number(inspectedQty)
      inspectedUomValue = cartonId && palletId ? inspectedQty : Number(inspectedUomValue)

      openPopup(
        html`
          <relocate-inventory-popup
            .bizplaceName="${this.bizplaceName}"
            .cycleCountNo="${this.cycleCountNo}"
            .currentCard="${currentCards}"
            .enableCartonLabel="${this._enableCartonLabel}"
            @relocate="${async e => {
              history.back()
              await this.fetchCycleCountWorksheet()
              this.pageUpdated()
              this.updateContext()
            }}"
          ></relocate-inventory-popup>
        `,
        {
          backdrop: true,
          size: 'medium',
          title: i18next.t('title.relocate_inventory')
        }
      )
    } catch (e) {
      this.showToast(e)
    }
  }

  async checkPalletInformation(palletId, bizplaceName) {
    try {
      const response = await client.query({
        query: gql`
          query checkInventoryOwner($palletId: String!, $bizplaceName: String!) {
            checkInventoryOwner(palletId: $palletId, bizplaceName: $bizplaceName)
          }
        `,
        variables: { palletId, bizplaceName }
      })

      if (!response.errors) {
        return response.data.checkInventoryOwner
      }
    } catch (e) {
      return false
    }
  }

  async completeCycleCount() {
    const result = await CustomAlert({
      title: i18next.t('title.are_you_sure'),
      text: i18next.t('text.complete_inspection'),
      confirmButton: { text: i18next.t('button.complete') },
      cancelButton: { text: i18next.t('button.cancel') }
    })

    if (!result.value) return

    CustomAlert({
      title: i18next.t('text.please_wait'),
      text: i18next.t('text.completing_inspection'),
      allowOutsideClick: false,
      allowEscapeKey: false
    })

    try {
      const response = await client.mutate({
        mutation: gql`
          mutation completeInspection($inventoryCheckNo: String!) {
            completeInspection(inventoryCheckNo: $inventoryCheckNo)
          }
        `,
        variables: { inventoryCheckNo: this.cycleCountNo }
      })

      if (!response.errors) {
        this.infoForm.reset()
        this.clearView()
        this.updateContext()
        await CustomAlert({
          title: i18next.t('title.completed'),
          text: i18next.t('text.inspection_is_completed'),
          confirmButton: { text: i18next.t('button.confirm') }
        })
      } else {
        await CustomAlert({
          title: i18next.t('title.error'),
          text: i18next.t('text.x_error', { state: { x: i18next.t('text.inspection') } }),
          confirmButton: { text: i18next.t('button.confirm') }
        })
      }
    } catch (e) {
      this.showToast(e)
    }
  }

  updateCurrentCard() {
    this._currentCard = this.data.records[this._arrayIndex] ? { ...this.data.records[this._arrayIndex] } : {}

    const currentStatus = this._currentCard.inventoryCheckItemStatus

    // Check the status and mark the currentCard as "checked" if it matches any status
    this._currentCard.checked = ['INSPECTED', 'RELOCATED', 'ADDED', 'NOT_TALLY'].includes(currentStatus)
  }

  resetInput() {
    this._currentCard.inspectedBatchInput = ''
    this._currentCard.inspectedQtyInput = 0
    if (!this._enableCartonLabel) {
      this._currentCard.inspectedUomValueInput = 0
    }
  }

  calculateCheckedInventoryCount() {
    this._currentCard.checkedInventoryCount = this.data.records.reduce((count, record) => {
      if (['INSPECTED', 'RELOCATED', 'ADDED', 'NOT_TALLY'].includes(record.relatedInvCheckItem.status)) {
        return count + 1
      }
      return count
    }, 0)
  }

  clearView() {
    this.data = { records: [] }
    this.cycleCountNo = null
    this.locationName = null
    this.cartonId = null
    this.palletId = null
    this.productInfo = null
    this.locationFilter = {}
    this.inventoryCheckItemStatus = null
    this._currentCard = {
      checkedInventoryCount: 0
    }
    this._selectedInventoryCheckItem = null
    this.formattedLocations = []
    this._editedCard = {}
    this.editMode = {
      inspectedBatchNo: false,
      inspectedQty: false,
      inspectedUomValue: false
    }
    this._arrayIndex = 0
    this.itemsPerPage = 1
    this.totalItems = 0
    this.inputForm.reset()
    this.infoForm.reset()
    this.updateContext()
  }

  nextCard() {
    this._arrayIndex = this._arrayIndex + 1
    this._disablePrevious = false
    this._scannedQty = 0
    this.pageUpdated()
    this.updateContext()
  }

  previousCard() {
    this._arrayIndex = this._arrayIndex - 1
    this._disableNext = false
    this._scannedQty = 0
    this.pageUpdated()
    this.updateContext()
  }

  _enableEditMode(field) {
    this._editMode = { ...this._editMode, [field]: true }
    this._editedCard = { ...this._editedCard, [field]: this._currentCard[field] }
  }

  _disableEditMode(field) {
    this._editMode = { ...this._editMode, [field]: false }
  }

  _handleEditInput(field, value) {
    this._editedCard = { ...this._editedCard, [field]: value }
  }

  _saveEdit(field) {
    this._currentCard = { ...this._currentCard, [field]: this._editedCard[field] }
    this._disableEditMode(field)
  }

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

window.customElements.define('inspecting-product', InspectingProduct)
