import { i18next, localize } from '@things-factory/i18n-base'
import { css, html, LitElement } from 'lit-element'
import { flattenObject } from '@things-factory/utils'
import '@material/mwc-icon'

class MobileConditionOfGoodsListing extends localize(i18next)(LitElement) {
  static get properties() {
    return {
      config: Object,
      fetchHandler: Function,
      _data: Array,
      _showSpinner: Boolean
    }
  }

  constructor() {
    super()
    this._data = []
    this._originalData = []
    this._showSpinner = false
    this._isExecuting = false // Flag to prevent fetching during confirmation
  }

  static get styles() {
    return [
      css`
        :host {
          display: flex;
          flex-direction: column;
          flex: 1;
          overflow: hidden;
          position: relative;
        }

        .list-container {
          flex: 1;
          overflow-y: auto;
        }

        .list-item {
          padding: 12px;
          color: #3a5877;
          border-bottom: solid 0.5px #3a5877;
          position: relative;
        }

        .list-item[dirty]::before {
          content: '';
          position: absolute;
          left: 0;
          top: 0;
          width: 0;
          height: 0;
          border-top: 12px solid #4caf50;
          border-right: 12px solid transparent;
        }

        .dirty-icon {
          position: absolute;
          left: 2px;
          top: 2px;
          color: white;
          font-size: 12px;
          z-index: 1;
        }

        .list-item:hover {
          background-color: var(--grid-record-hover-background-color, #f0f0f0);
        }

        .list-item[selected] {
          background-color: var(--grid-record-selected-background-color, #e3f2fd);
        }

        .field-row {
          display: flex;
          flex-direction: row;
          align-items: center;
          padding: 0px;
          gap: 16px;
        }

        .field-label {
          font-weight: bold;
          text-transform: capitalize;
          font-size: 14px;
          min-width: 150px;
          color: #3a5877;
        }

        .field-value {
          font-size: 14px;
          color: #3a5877;
          flex: 1;
        }

        .field-col {
          display: flex;
          flex-direction: row;
          align-items: center;
          gap: 16px;
          width: 100%;
        }

        .selection-box {
          flex: 1;
          max-width: 300px;
          padding: 6px;
          border: 1px solid #ccc;
          border-radius: 4px;
          font-size: 14px;
          background-color: var(--theme-white-color);
          color: #3a5877;
        }

        .selection-box:focus {
          outline: none;
          border-color: var(--primary-color);
        }

        oops-spinner {
          display: none;
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
        }

        oops-spinner[show] {
          display: block;
        }

        oops-note {
          display: block;
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
        }
      `
    ]
  }

  firstUpdated() {
    this._fetchData()
  }

  updated(changedProperties) {
    // Like data-grist: only update handler reference when fetchHandler changes, don't fetch
    if (changedProperties.has('fetchHandler')) {
      // Just update the reference, don't fetch automatically
      // Fetch will be called explicitly via fetch() method when needed
    }
    
    // Only fetch when config changes (like data-grist does)
    if (changedProperties.has('config') && !this._isExecuting && !this._showSpinner) {
      this._fetchData()
    }
  }

  async _fetchData() {
    if (!this.fetchHandler || !this.config) return
    
    // Don't fetch if we're currently executing (e.g., during confirmation)
    if (this._isExecuting) return

    this._showSpinner = true
    this.requestUpdate()

    try {
      const result = await this.fetchHandler({
        page: 1,
        limit: 9999 // Fetch all records for mobile view
      })

      // Only update data if we're not executing (to prevent resetting during confirmation)
      if (!this._isExecuting) {
        this._data = result.records || []
        this._originalData = this._data.map(record => ({ ...record }))
      }
    } catch (error) {
      console.error('Error fetching data:', error)
      if (!this._isExecuting) {
        this._data = []
        this._originalData = []
      }
    } finally {
      // Only hide spinner if we're not executing (spinner is controlled externally during execution)
      if (!this._isExecuting) {
        this._showSpinner = false
        this.requestUpdate()
      }
    }
  }

  _onSelectionChange(e, record, field) {
    const newValue = e.target.value
    
    // Update the record
    const updatedRecord = {
      ...record,
      [field]: newValue
    }

    // Update in data array
    const index = this._data.findIndex(r => r.id === record.id)
    if (index !== -1) {
      this._data[index] = updatedRecord
    }

    // Trigger re-render to show dirty indicator
    this.requestUpdate()

    // Dispatch change event
    this.dispatchEvent(
      new CustomEvent('field-change', {
        bubbles: true,
        composed: true,
        detail: {
          record: updatedRecord,
          field: field,
          value: newValue,
          originalRecord: record
        }
      })
    )
  }

  _isRecordDirty(record) {
    const original = this._originalData.find(r => r.id === record.id)
    if (!original) return false
    return original.conditionOfGoods !== record.conditionOfGoods
  }

  _renderField(fieldConfig, record) {
    const fieldType = fieldConfig.type || 'text'
    const field = fieldConfig.field
    const header = fieldConfig.header
    const value = record[field]
    const fieldColor = fieldConfig.color || '#3A5877'
    
    switch (fieldType) {
      case 'selectionBox':
        const options = fieldConfig.options || []
        const optionValueKey = fieldConfig.optionValueKey || 'value'
        const optionLabelKey = fieldConfig.optionLabelKey || 'label'
        const currentValue = value || ''

        return html`
          <div class="field-row">
            <div class="field-label" style="color: ${fieldColor}">${header || ''}</div>
            <select
              class="selection-box"
              .value="${String(currentValue)}"
              @change="${e => this._onSelectionChange(e, record, field)}"
              style="color: ${fieldColor}"
            >
              ${fieldConfig.placeholder
                ? html`<option value="">${fieldConfig.placeholder}</option>`
                : ''}
              ${options.map(option => {
                const optValue = typeof option === 'object' ? option[optionValueKey] : option
                const optLabel = typeof option === 'object' ? option[optionLabelKey] : option
                const isSelected = String(optValue) === String(currentValue)
                return html`<option value="${optValue}" ?selected="${isSelected}">${optLabel}</option>`
              })}
            </select>
          </div>
        `
      case 'text':
      default:
        return html`
          <div class="field-row">
            <div class="field-label" style="color: ${fieldColor}">${header || ''}</div>
            <div class="field-value" style="color: ${fieldColor}">${value || '-'}</div>
          </div>
        `
    }
  }

  render() {
    if (!this.config || !this.fetchHandler) {
      return html``
    }

    var oops = !this._showSpinner && (!this._data || this._data.length === 0)

    return html`
      ${oops
        ? html` <oops-note icon="list" title="EMPTY LIST" description="There are no records to be shown"></oops-note> `
        : html``}
        <div class="list-container">
            ${this._data.map(record => {
            try {
                const flattenedRecord = flattenObject(record, '.')
                const isDirty = this._isRecordDirty(record)
                return html`
                <div class="list-item" ?dirty=${isDirty}>
                    ${isDirty ? html`<mwc-icon class="dirty-icon">done</mwc-icon>` : ''}
                    ${this.config.columns.map(columnConfig => this._renderField(columnConfig, flattenedRecord))}
                </div>
                `
            } catch (e) {
                console.error('Error rendering record:', e)
                return html``
            }
            })}
        </div>
        <oops-spinner ?show=${this._showSpinner}></oops-spinner>
    `
  }

  fetch() {
    this._fetchData()
  }

  getRecords() {
    return this._data
  }

  getChangedRecords() {
    return this._data.filter(record => {
      const original = this._originalData.find(r => r.id === record.id)
      if (!original) return false
      return original.conditionOfGoods !== record.conditionOfGoods
    })
  }

  showSpinner() {
    this._showSpinner = true
    this._isExecuting = true // Prevent fetching during execution
    this.requestUpdate()
  }

  hideSpinner() {
    this._showSpinner = false
    this._isExecuting = false
    this.requestUpdate()
  }
}

window.customElements.define('mobile-condition-of-goods-listing', MobileConditionOfGoodsListing)
