import gql from 'graphql-tag'
import { html, css, LitElement } from 'lit-element'
import { client, CustomAlert } from '@things-factory/shell'
import { i18next, localize } from '@things-factory/i18n-base'
import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
import { ScrollbarStyles } from '@things-factory/styles'
import '../../components/list-view/product-list-view'
import { showToast } from '../../../util'

class DeliveryOrderInfo extends localize(i18next)(LitElement) {
  static get properties() {
    return {
      _doNo: String,
      _truckNo: String,
      data: Object
    }
  }

  static get styles() {
    return [
      ScrollbarStyles,
      css`
        :host {
          padding: 12px;
          display: flex;
          flex-direction: column;
          overflow: hidden;
          background-color: var(--main-section-background-color);
        }
        .do-info {
          display: grid;
          grid-template-columns: repeat(12, 1fr);
          grid-gap: 8px;
          color: #3a5877;
          padding: 0 0 12px 0;
          margin: 0 0 12px 0;
          border-bottom: solid 0.5px #3a5877;
        }
        .do-info-title {
          grid-column: span 3;
          font-size: 12px;
          font-weight: 600;
          color: #3a5877;
        }
        .do-info-description {
          grid-column: span 9;
          font-size: 12px;
        }
        .tab {
          display: flex;
          justify-content: space-between;
          color: #f3f2f7;
          background-color: #007e7f;
          padding: 10px;
        }
        .content {
          display: block;
          flex: 1;
          overflow-y: auto;
        }
        .text-14 {
          font-size: 14px !important;
          line-height: 1.5 !important;
        }
        .font-bold {
          font-weight: bold !important;
        }
        .button-container {
          position: absolute;
          bottom: 12px;
          right: 12px;
          display: flex;
          gap: 8px;
        }
        [danger] {
          background: var(--mdc-danger-button-primary-color);
          border-radius: 4px;
        }
        [outlined] {
          background: var(--main-section-background-color);
        }
        .color-white {
          color: var(--main-section-background-color);
        }
      `
    ]
  }

  get deliveryInfoConfig() {
    return {
      columnLeft: {
        size: 8,
        fields: [
          {
            type: 'row',
            content: [
              {
                header: 'Product Name',
                field: 'product.name',
                type: 'string',
                style: '-webkit-line-clamp: 2;'
              }
            ]
          },
          { type: 'row', content: [{ header: 'SKU No.', field: 'product.sku', type: 'string' }] },
          {
            type: 'row',
            content: [
              { header: 'Exp Date', field: 'inventory.expirationDate', type: 'string' },
              { header: 'Batch No', field: 'batchId', type: 'string' }
            ]
          },
          {
            type: 'row',
            content: [
              { header: 'Packing Size', field: 'packingSize', type: 'string' },
              { header: 'Packing Type', field: 'packingType', type: 'string' }
            ]
          }
        ]
      },
      columnRight: {
        size: 4,
        fields: [
          {
            type: 'valueBox',
            content: { header: 'Qty.', field: 'pickedQty', type: 'string' }
          }
        ]
      }
    }
  }

  render() {
    return html`
      <!-- Header Form Section -->
      <div class="do-info">
        <label class="do-info-title">Name</label>
        <label class="do-info-description">: ${this._doNo}</label>

        <label class="do-info-title">Truck No</label>
        <label class="do-info-description">: ${this._truckNo}</label>
      </div>
      <!-- Header Form Section End -->

      <!-- Tab Info Section -->
      <div class="tab text-center">
        <label class="text-14 font-bold">Total SKU: ${this._getTotalSku()}</label>
      </div>
      <!-- Tab Info Section End -->

      <!-- Content Section -->
      <div class="content">
        <product-list-view .config=${this.deliveryInfoConfig} .data=${this._getGroupedOrderInventories()}></product-list-view>
      </div>
      <!-- Content Section End -->

      <div class="button-container">
        <mwc-button danger @click=${e => this.undoLoad(e)}
          ><label class="color-white">${i18next.t('button.undo')}</label></mwc-button
        >
        <mwc-button outlined @click=${e => this.closePopup(e)}>${i18next.t('button.back')}</mwc-button>
      </div>
    `
  }

  async undoLoad() {
    try {
      // Validate data exists before proceeding
      if (!this.data?.id) {
        throw new Error('Delivery order data is not available')
      }

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

      if (!result.value) return

      const doId = this.data.id

      const response = await client.mutate({
        mutation: gql`
          mutation undoLoad($doId: String!) {
            undoLoad(doId: $doId)
          }
        `,
        variables: { doId }
      })

      if (!response.errors) {
        // Dispatch event with bubbles and composed to ensure proper propagation through shadow DOM
        this.dispatchEvent(new CustomEvent('undo', {
          detail: { doId },
          bubbles: true,
          composed: true
        }))
        // Small delay to allow event handler to process before closing popup
        setTimeout(() => history.back(), 100)
      } else {
        throw new Error(response.errors[0]?.message || 'Failed to undo loading')
      }
    } catch (e) {
      showToast({ type: 'error', message: e.message || 'Failed to undo loading' })
    }
  }

  _getTotalSku() {
    if (!this.data?.orderInventories?.length) return 0
    // Count unique products by SKU
    const uniqueSkus = new Set(
      this.data.orderInventories.map(oi => oi.product?.sku).filter(Boolean)
    )
    return uniqueSkus.size
  }

  /**
   * Groups order inventories by SKU, batchId, expirationDate, packingType, and packingSize.
   * Sums the pickedQty for items with the same grouping key.
   * @returns {Array} Grouped order inventories with aggregated quantities
   */
  _getGroupedOrderInventories() {
    if (!this.data?.orderInventories?.length) return []

    const groupedMap = new Map()

    this.data.orderInventories.forEach(oi => {
      // Create a unique key based on product details (expirationDate is on inventory relation)
      const expirationDate = oi.inventory?.expirationDate || ''
      const key = `${oi.product?.sku || ''}_${oi.batchId || ''}_${expirationDate}_${oi.packingType || ''}_${oi.packingSize || ''}`

      if (groupedMap.has(key)) {
        const existing = groupedMap.get(key)
        // Sum the quantities
        existing.pickedQty = (existing.pickedQty || 0) + (oi.pickedQty || 0)
        existing.releaseQty = (existing.releaseQty || 0) + (oi.releaseQty || 0)
      } else {
        // Create a new entry with a copy of the order inventory
        groupedMap.set(key, { ...oi })
      }
    })

    return Array.from(groupedMap.values())
  }

  closePopup() {
    history.back()
  }
}

window.customElements.define('delivery-order-info', DeliveryOrderInfo)
