import { createParentsIterator } from './ParentsIterator.js'
import { StateProvider } from './Provider.js'

class StateConsumer extends HTMLElement {
  constructor() {
    super()
    this.provider = null
    this.appendChild(document.createElement('slot'))
  }

  get name() {
    return this.getAttribute('name')
  }

  /** Returns the value of the corresponding provider */
  get value() {
    return this.provider ? this.provider.value : null
  }

  connectedCallback() {
    this.provider = this.findProvider()
    if (this.provider) {
      this.provider.addObserver(this)
    }
    this.update(this.provider)
  }

  disconnectedCallback() {
    this.provider.removeObserver(this)
  }

  /**
   * Traverses tree upwards until a Provider with the same name is found
   * Returns the closest provider or null if none is existent
   */
  findProvider() {
    for (let node of createParentsIterator(this)) {
      if (node instanceof StateProvider && node.name === this.name) {
        return node
      }
    }
    return null
  }

  update({ value }) {
    if (typeof this.onChange === 'function') {
      this.onChange(value)
    }
  }
}

window.customElements.define('state-consumer', StateConsumer)
