import { Filter } from '@nostr/tools/filter'
import { AddressPointer, decodeNostrURI, EventPointer } from '@nostr/tools/nip19'
import { NostrEvent } from '@nostr/tools/pure'
import { normalizeURL } from '@nostr/tools/utils'

import { getOutboxRelaysFor, pool } from './nostr.js'
import { debounce } from './utils.js'

export default class NostrEventJson extends HTMLElement {
  static observedAttributes = ['ref', 'event']

  constructor() {
    super()

    this.attachShadow({ mode: 'open' })
  }

  connectedCallback() {
    this.style.display = 'inline-block'
    this.style.width = 'fit-content'
    this.style.height = 'fit-content'
    this.set()
  }

  attributeChangedCallback() {
    this.set()
  }

  set: () => void = debounce(async () => {
    let evt: NostrEvent | null = null

    let eventj = this.getAttribute('event')
    if (eventj) {
      try {
        evt = JSON.parse(eventj)
      } catch {
        /***/
      }
    }

    if (!evt) {
      let input = this.getAttribute('ref')
      if (input) {
        let { type, data } = decodeNostrURI(input)
        let relays: string[] = []
        let author: string | undefined
        let filter: Filter
        if (type === 'nevent') {
          let d = data as EventPointer
          relays = d.relays || []
          author = d.author
          filter = { ids: [d.id] }
        } else if (type === 'naddr') {
          let d = data as AddressPointer
          filter = { authors: [d.pubkey], '#d': [d.identifier], kinds: [d.kind] }
          relays = d.relays || []
          author = d.pubkey
        } else if (type === 'note') {
          filter = { ids: [data as string] }
        } else if (input.match(/[0-9a-f]{64}/)) {
          filter = { ids: [input] }
        } else {
          return
        }

        relays = relays.map(normalizeURL)

        if (author) relays = await getOutboxRelaysFor(author)
        evt = await pool.get(relays, filter)
      }
    }

    if (evt) {
      const { shadowRoot } = this
      shadowRoot!.innerHTML = `<pre part="pre" style="white-space: pre-wrap; word-break: break-all">{
  <span part="key">"id":</span> <span part="id" id="id"></span>
  <span part="key">"pubkey":</span> <span part="pubkey" id="pubkey"></span>
  <span part="key">"kind":</span> <span part="kind" id="kind"></span>
  <span part="key">"created_at":</span> <span part="created_at" id="created_at"></span>
  <span part="key">"tags":</span> <span part="tags" id="tags"></span>
  <span part="key">"content":</span> <span part="content" id="content"></span>
  <span part="key">"sig":</span> <span part="sig" id="sig"></span>
}</pre>`
      shadowRoot!.getElementById('id')!.textContent = evt.id
      shadowRoot!.getElementById('pubkey')!.textContent = evt.pubkey
      shadowRoot!.getElementById('kind')!.textContent = `${evt.kind}`
      shadowRoot!.getElementById('created_at')!.textContent = `${evt.created_at}`
      shadowRoot!.getElementById('tags')!.textContent = JSON.stringify(evt.tags)
      shadowRoot!.getElementById('content')!.textContent = evt.content
      shadowRoot!.getElementById('sig')!.textContent = evt.sig
    }
  }, 200)
}

window.customElements.define('nostr-event-json', NostrEventJson)
