import '@things-factory/grist-ui'
import '@material/mwc-button'

import { css, html, LitElement } from 'lit-element'

import { MultiColumnFormStyles, SingleColumnFormStyles } from '@things-factory/form-ui'
import { i18next, localize } from '@things-factory/i18n-base'

class RouteLabelHistoryDialog extends localize(i18next)(LitElement) {
  static get styles() {
    return [
      MultiColumnFormStyles,
      SingleColumnFormStyles,
      css`
        :host {
          padding: 10px;
          display: flex;
          flex-direction: column;
          overflow: hidden;
          background-color: var(--main-section-background-color);
          height: 100%;
          max-height: calc(100vh - 200px);
        }
        .history-dialog-content {
          display: flex;
          flex-direction: column;
          gap: 12px;
          flex: 1;
          min-height: 0;
          overflow: hidden;
        }
        .history-grist {
          flex: 1;
          min-height: 0;
          border: 1px solid var(--form-border-color);
          background: var(--main-section-background-color);
          overflow: hidden;
        }
        .history-grist data-grist {
          height: 100%;
          overflow-y: auto;
        }
        .button-container {
          padding: 10px 0 12px 0;
          text-align: center;
          flex-shrink: 0;
        }
      `
    ]
  }

  static get properties() {
    return {
      target: Object,
      logs: Array,
      appendSeqField: String,
      routeLabel: Object,
      onReprint: Function
    }
  }

  constructor() {
    super()
    this.logs = []
    this._historyReprintSeq = ''
  }

  get historyGrist() {
    return this.shadowRoot.querySelector('#history-grist')
  }

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

  _validateSequence(seq) {
    if (!seq || !seq.trim()) {
      return { valid: false, error: '' }
    }

    const seqTrimmed = seq.trim()

    // Check for decimal points in the input
    // Split by comma first to check each part separately
    const parts = seqTrimmed.split(',')
    for (const part of parts) {
      if (!part) continue
      const trimmedPart = part.trim()
      // Check if the part contains a decimal point
      if (trimmedPart.includes('.')) {
        return {
          valid: false,
          error: i18next.t('text.print_qty_must_be_integer')
        }
      }
      // Check if it's a range (contains '-')
      if (trimmedPart.includes('-')) {
        const rangeParts = trimmedPart.split('-')
        for (const rangePart of rangeParts) {
          const trimmedRangePart = rangePart.trim()
          if (trimmedRangePart.includes('.')) {
            return {
              valid: false,
              error: i18next.t('text.print_qty_must_be_integer')
            }
          }
        }
      }
    }

    // Parse the input to support ranges (e.g., "1-2") and specific numbers (e.g., "1" or "1,3,5-7")
    const parseSeqInput = input => {
      if (!input || typeof input !== 'string') return []
      const cleaned = input.replace(/\s/g, '')
      if (!cleaned) return []
      const parts = cleaned.split(',')
      const numbers = new Set()
      for (const part of parts) {
        if (!part) continue
        const range = part.split('-')
        if (range.length === 1) {
          const n = parseInt(range[0], 10)
          if (Number.isFinite(n) && n > 0) numbers.add(n)
        } else if (range.length === 2) {
          const a = parseInt(range[0], 10)
          const b = parseInt(range[1], 10)
          if (Number.isFinite(a) && Number.isFinite(b) && a > 0 && b > 0) {
            const from = Math.min(a, b)
            const to = Math.max(a, b)
            for (let i = from; i <= to; i++) numbers.add(i)
          }
        }
      }
      return Array.from(numbers).sort((x, y) => x - y)
    }

    const parsedSeqs = parseSeqInput(seqTrimmed)
    if (parsedSeqs.length === 0) {
      return { valid: false, error: i18next.t('text.invalid_sequence_number') }
    }

    // Check if all parsed sequences fall within any of the history ranges
    const allValid = parsedSeqs.every(seqNum => {
      return (this.logs || []).some(log => {
        const from = parseInt(log.from, 10)
        const to = parseInt(log.to, 10)
        return !isNaN(from) && !isNaN(to) && seqNum >= from && seqNum <= to
      })
    })

    if (!allValid) {
      const ranges = (this.logs || []).map(log => `${log.from}-${log.to}`).join(', ')
      return {
        valid: false,
        error: i18next.t('text.sequence_out_of_range', { ranges })
      }
    }

    return { valid: true, error: '' }
  }

  render() {
    return html`
      <div class="history-dialog-content">
        <form class="multi-column-form">
          <label>${i18next.t('field.ro')}</label>
          <input disabled .value="${this.target?.name || ''}" />

          <label>${i18next.t('field.sequence_reference')}</label>
          <input
            disabled
            .value="${this.appendSeqField === 'refNo'
              ? i18next.t('field.ref_no')
              : this.appendSeqField === 'refNo2'
              ? i18next.t('field.ref_no_2')
              : i18next.t('field.ref_no_3')}"
          />

          <label>${i18next.t('field.reprint_seq')}</label>
          <input
            placeholder="${i18next.t('text.reprint_seq_placeholder')}"
            .value="${this._historyReprintSeq || ''}"
            @input="${e => {
              this._historyReprintSeq = e.currentTarget.value
            }}"
          />
        </form>

        <div class="history-grist">
          <data-grist
            id="history-grist"
            .mode=${'GRID'}
            .config=${{
              pagination: { infinite: true },
              rows: { appendable: false, selectable: false },
              list: { fields: ['range', 'printedAt', 'creatorName'] },
              columns: [
                { type: 'gutter', gutterName: 'sequence' },
                { type: 'string', name: 'range', header: i18next.t('field.range'), width: 160 },
                { type: 'string', name: 'printedAt', header: i18next.t('field.printed_at'), width: 190 },
                { type: 'string', name: 'creatorName', header: i18next.t('field.last_printed_by'), width: 140 }
              ]
            }}
            .data=${{ records: this.logs || [], total: (this.logs || []).length }}
          ></data-grist>
        </div>
      </div>

      <div class="button-container">
        <mwc-button
          raised
          danger
          @click="${async () => {
            if (this.onReprint) {
              const reprintSeq = (this._historyReprintSeq || '').trim()
              if (!reprintSeq) {
                // Show toast message - handled in _reprintSelectedFromHistory
                await this.onReprint(reprintSeq)
                return
              }

              // Validate sequence before reprinting
              const validation = this._validateSequence(reprintSeq)
              if (!validation.valid) {
                if (validation.error) {
                  this._showToast({
                    type: 'error',
                    message: validation.error
                  })
                }
                return
              }

              await this.onReprint(reprintSeq)
            }
          }}"
        >
          ${i18next.t('button.reprint')}
        </mwc-button>
        <mwc-button @click="${() => history.back()}">${i18next.t('button.cancel')}</mwc-button>
      </div>
    `
  }
}

window.customElements.define('route-label-history-dialog', RouteLabelHistoryDialog)
