TanStack
import { LitElement, html } from 'lit'
import { styleMap } from 'lit/directives/style-map.js'
import { TanStackDevtoolsCore } from '@tanstack/devtools'
import { pacerDevtoolsPlugin } from '@tanstack/pacer-devtools'
import { queue } from '@tanstack/lit-pacer/queuer'

class Counter extends LitElement {
  static properties = {
    queueItems: { state: true },
    processedCount: { state: true },
  }
  queueItems: Array<number> = []
  processedCount = 0
  processQueueItem = (item: number) => {
    console.log('Processing item:', item)
  }
  queueItem = queue<number>(this.processQueueItem, {
    key: 'Add Number Queue',
    maxSize: 25,
    wait: 1000,
    onItemsChange: (queue) => {
      this.queueItems = queue.peekAllItems()
    },
    onExecute: (_item, queue) => {
      this.processedCount = queue.store.state.executionCount
    },
  })
  override createRenderRoot() {
    return this
  }
  override render() {
    return html`<div>
      <h1>TanStack Pacer queue Example 1</h1>
      <table>
        <tbody>
          <tr>
            <td>Queue Size:</td>
            <td>${this.queueItems.length}</td>
          </tr>
          <tr>
            <td>Items Processed:</td>
            <td>${this.processedCount}</td>
          </tr>
          <tr>
            <td>Queue Items:</td>
            <td>${this.queueItems.join(', ')}</td>
          </tr>
        </tbody>
      </table>
      <button
        @click=${() => {
          const nextNumber = this.queueItems.length
            ? this.queueItems[this.queueItems.length - 1]! + 1
            : 1
          this.queueItem(nextNumber)
        }}
        ?disabled=${this.queueItems.length >= 25}
      >
        Add Number
      </button>
    </div>`
  }
}
customElements.define('pacer-counter', Counter)
class Search extends LitElement {
  static properties = {
    queueItems: { state: true },
    processedCount: { state: true },
    inputText: { state: true },
    queuedText: { state: true },
  }
  queueItems: Array<string> = []
  processedCount = 0
  inputText = ''
  queuedText = ''
  processQueueItem = (item: string) => {
    this.queuedText = item
  }
  queueTextChange = queue<string>(this.processQueueItem, {
    key: 'Text Change Queue',
    maxSize: 100,
    wait: 500,
    onItemsChange: (queue) => {
      this.queueItems = queue.peekAllItems()
    },
    onExecute: (_item, queue) => {
      this.processedCount = queue.store.state.executionCount
    },
  })
  handleInputChange = (e: Event) => {
    this.inputText = (e.target as HTMLInputElement).value
    this.queueTextChange((e.target as HTMLInputElement).value)
  }
  override createRenderRoot() {
    return this
  }
  override render() {
    return html`<div>
      <h1>TanStack Pacer queue Example 2</h1>
      <div>
        <input
          type="search"
          .value=${this.inputText}
          @input=${this.handleInputChange}
          placeholder="Type to add to queue..."
          style=${styleMap({ width: '100%' })}
        />
      </div>
      <table>
        <tbody>
          <tr>
            <td>Queued Text:</td>
            <td>${this.queuedText}</td>
          </tr>
          <tr>
            <td>Queue Size:</td>
            <td>${this.queueItems.length}</td>
          </tr>
          <tr>
            <td>Items Processed:</td>
            <td>${this.processedCount}</td>
          </tr>
          <tr>
            <td>Queue Items:</td>
            <td>${this.queueItems.join(', ')}</td>
          </tr>
        </tbody>
      </table>
    </div>`
  }
}
customElements.define('pacer-search', Search)
class Range extends LitElement {
  static properties = {
    queueItems: { state: true },
    processedCount: { state: true },
    currentValue: { state: true },
    queuedValue: { state: true },
  }
  queueItems: Array<number> = []
  processedCount = 0
  currentValue = 50
  queuedValue = 50
  processQueueItem = (item: number) => {
    this.queuedValue = item
  }
  queueValue = queue<number>(this.processQueueItem, {
    key: 'Range Change Queue',
    maxSize: 100,
    wait: 100,
    onItemsChange: (queue) => {
      this.queueItems = queue.peekAllItems()
    },
    onExecute: (_item, queue) => {
      this.processedCount = queue.store.state.executionCount
    },
  })
  handleRangeChange = (e: Event) => {
    const newValue = parseInt((e.target as HTMLInputElement).value, 10)
    this.currentValue = newValue
    this.queueValue(newValue)
  }
  override createRenderRoot() {
    return this
  }
  override render() {
    return html`<div>
      <h1>TanStack Pacer queue Example 3</h1>
      <div style=${styleMap({ marginBottom: '20px' })}>
        <label
          >Current Range:<input
            type="range"
            min="0"
            max="100"
            .value=${this.currentValue}
            @input=${this.handleRangeChange}
            style=${styleMap({ width: '100%' })}
          /><span>${this.currentValue}</span></label
        >
      </div>
      <div style=${styleMap({ marginBottom: '20px' })}>
        <label
          >Queued Range (Readonly):<input
            type="range"
            min="0"
            max="100"
            .value=${this.queuedValue}
            disabled
            style=${styleMap({ width: '100%' })}
          /><span>${this.queuedValue}</span></label
        >
      </div>
      <table>
        <tbody>
          <tr>
            <td>Queue Size:</td>
            <td>${this.queueItems.length}</td>
          </tr>
          <tr>
            <td>Items Processed:</td>
            <td>${this.processedCount}</td>
          </tr>
          <tr>
            <td>Queue Items:</td>
            <td>${this.queueItems.join(', ')}</td>
          </tr>
        </tbody>
      </table>
    </div>`
  }
}
customElements.define('pacer-range', Range)
class Example extends LitElement {
  private devtools?: TanStackDevtoolsCore
  private target?: HTMLDivElement
  override createRenderRoot() {
    return this
  }
  override connectedCallback() {
    super.connectedCallback()

    if (!import.meta.env.DEV) return
    this.target = document.createElement('div')
    document.body.append(this.target)
    this.devtools = new TanStackDevtoolsCore({
      plugins: [pacerDevtoolsPlugin()],
    })
    this.devtools.mount(this.target)
  }
  override disconnectedCallback() {
    this.devtools?.unmount()
    this.target?.remove()
    this.devtools = undefined
    this.target = undefined

    super.disconnectedCallback()
  }
  override render() {
    return html`<div>
      <pacer-counter></pacer-counter>
      <hr />
      <pacer-search></pacer-search>
      <hr />
      <pacer-range></pacer-range>
    </div>`
  }
}
customElements.define('pacer-example', Example)
document.getElementById('app')!.append(document.createElement('pacer-example'))