/**
 * Prints VRE d4s-social-posts (from @from to @quantity number)
 */
window.customElements.define('d4s-social-posts', class extends HTMLElement {

  #basepath = 'https://api.d4science.org'

  #from = 1
  #quantity = 10
  #nextIdx = null
  #busy = false

  #boot = null
  #shadowRoot = null
  #unorderedlist = null

  //#restRecentPosts = '/rest/2/posts/get-posts-vre' // old get, gets all posts unfiltered
  #restRecentPosts = '/rest/2/posts/get-recent-posts-vre-by-range'
  #restComments = '/rest/2/comments/get-comments-by-post-id'

  #style = `<style>
    .d4s-social-posts {
      list-style: none;
      padding-left: 0;
    }
    .d4s-social-post {
      margin: 5px 0 5px 0;
      padding: 5px 0 5px 0;
      border-bottom: 1px solid lightgray;
    }
    .d4s-social-post:last-child {
      border-bottom: none;
    }
    .d4s-post-heading {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin-bottom: 5px;
    }
    .d4s-post-avatar img {
      object-fit: cover;
      width: 40px;
      height: 40px;
      border-radius: 50%;
    }
    .d4s-post-meta {
      display: flex;
      flex-flow: column;
    }
    .d4s-post-meta .fullname {
      font-weight: bold;
    }
    .d4s-post-meta .time {
      font-size: small;
    }
    .d4s-post-body {
      color: var(--color);
    }
    .d4s-post-footer {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
    }
    .d4s-post-comments {
      list-style: none;
    }
    .d4s-post-comment {
      display: flex;
      flex-wrap: wrap;
      gap: 5px;
    }
    .d4s-comment-avatar img {
      object-fit: cover;
      width: 40px;
      height: 40px;
      border-radius: 50%;
    }
    .d4s-comment {
      font-size: small;
      margin: 0 5px;
    }
    .d4s-comment-body {
      padding: 6px;
      background-color: #f0f0f0;
      border-radius: 9px;
    }
    .d4s-comment-body .fullname {
      font-weight: bold;
    }
    .d4s-comment-footer {
      margin: 3px 5px 6px 5px;
    }
    .d4s-post-footer {
      margin: 8px 0 6px 0;
    }
    .comments-nr {
      display: flex;
      gap: 5px;
    }
    .likes-nr {
      display: flex;
      gap: 5px;
    }
    .d4s-post-attachment {
      word-break: break-word;
      font-size: small;
      margin-top: 8px;
      display: flex;
      border: 1px solid lightgray;
      border-radius: 2px;
    }
    .d4s-post-attachment .attachment-div {
      display: contents;
    }
    .d4s-post-attachment .attachment-img {
      object-fit: cover;
      width: 120px;
      height: 100px;
    }
    .d4s-post-attachment .attachment-info {
      display: flex;
      flex-flow: column;
      gap: 8px;
      padding: 8px;
      background-color: #f0f0f0;
      flex: 1;
    }
    .d4s-post-attachment .attachment-info .title {
      word-break: break-word;
    }
  </style>`

  constructor() {
    super()
    this.#boot = document.querySelector("d4s-boot-2")
    this.#shadowRoot = this.attachShadow({mode: 'open'})
    var template = document.createElement('template')
    template.innerHTML = this.#style
    this.#shadowRoot.appendChild(template.content.cloneNode(true))
    var ul = document.createElement('ul')
    ul.classList.add('d4s-social-posts')
    this.#unorderedlist = ul
    this.#shadowRoot.appendChild(ul)
  }

  connectedCallback() {
    if (this.#boot) {
      this.#nextIdx = this.#from
      this.loadPosts()
    } else {
      console.error('<d4s-boot-2> webcomponent not found in this page')
    }
  }

  loadPosts(nr) {
    if (this.#busy) {
      return

    } else {
      this.#busy = true
      const url = new URL(this.#basepath + this.#restRecentPosts)
      if (this.#nextIdx <= 0) {
        this.#busy = false
        throw 'Out of range index found'
      }
      var quparam = nr ? Number(nr) : this.#quantity
      var params = {from: this.#nextIdx, quantity: quparam }
      url.search = new URLSearchParams(params).toString()
      console.log("url=" + url.href)

      this.#boot.secureFetch(url).then(reply => {
        if(reply.status !== 200) throw "status=" + reply.status
        return reply.json()

      }).then(data => {
        //console.log(data)
        //this.#nextIdx = Number(data.result.last_returned_post_timeline_index)
        this.#nextIdx = Number(data.result.last_returned_post_timeline_index) - 1
        //this.#nextIdx = this.#from + this.#quantity
        this.renderPosts(data.result.posts)
        //this.rawRenderResponse(data)

      }).catch(err => {
        const msg = 'Unable to load posts. '
        console.error(msg + err)
        throw msg
      }).finally(() => {

        this.#busy = false
      })
    }
  }

  morePosts(nr) {
    this.loadPosts(nr)
  }

  renderPosts(posts) {
    const ul = this.#unorderedlist
    posts.forEach(post => {
      //console.log(post)
      var li = document.createElement('li')
      li.id = post.key
      li.classList.add('d4s-social-post')
      const thumbnail = (!post.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + post.thumbnail_url : post.thumbnail_url
      const datetime = new Date(0)
      datetime.setUTCMilliseconds(post.time)
      const datetimestr = datetime.toLocaleString([], {year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit'})
      li.innerHTML = `
        <div class="d4s-post-heading">
          <div class="d4s-post-avatar">
            <img src="${thumbnail}" onerror="this.style.display='none'"></slot>
          </div>
          <div class="d4s-post-meta">
            <div class="fullname">${post.full_name}</div>
            <div class="time">${datetimestr}</div>
          </div>
        </div>
        <div class="d4s-post-body">${post.description}</div>
        <div class="d4s-post-attachment"></div>
        <div class="d4s-post-footer"></div>
      `

      if (post.comments_no != "0") {
        var commsnr = document.createElement('div')
        commsnr.classList.add('comments-nr')
        commsnr.innerHTML += `
          <img src="assets/comment-ellipsis.svg" width="18"/>
          <span>${post.comments_no}</span>
        `
        li.querySelector('.d4s-post-footer').appendChild(commsnr)
      }

      if (post.likes_no != "0") {
        var likesnr = document.createElement('div')
        likesnr.classList.add('likes-nr')
        likesnr.innerHTML += `
          <img src="assets/thumbs-up.svg" width="18" />
          <span>${post.likes_no}</span>
        `
        li.querySelector('.d4s-post-footer').appendChild(likesnr)
      }

      if (post.link_title !== "") {
        var attimg = document.createElement('div')
        attimg.classList.add('attachment-div')
        if (post.uri_thumbnail != "null") {
          attimg.innerHTML += `<img src="${post.uri_thumbnail}" class="attachment-img" onerror="this.style.display='none'"/>`
          li.querySelector('.d4s-post-attachment').appendChild(attimg)
        }
        var attdesc = document.createElement('div')
        attdesc.classList.add('attachment-info')
        attdesc.innerHTML += `
          <div class="title"><a href="${post.uri}">${post.link_title}</a></div>
          <div class="url">${post.uri}</div>
          <div class="description">${post.link_description}</div>
        `
        li.querySelector('.d4s-post-attachment').appendChild(attdesc)
      } else {
        li.querySelector('.d4s-post-attachment').remove()
      }

      ul.appendChild(li)

      let aimg = li.querySelector(".attachment-img")
      if (aimg) {
        aimg.addEventListener('load', (ev) => {
          let prop = aimg.naturalWidth / aimg.naturalHeight
          if (prop < 0.5 || prop > 2) {
            aimg.style.objectFit = 'contain'
          }
        })
      }

      if (post.comments_no > 0) {
        this.fetchComments(post.key)
      }
    })
  }

  rawRenderResponse(data) {
    var pre = document.createElement('pre')
    pre.innerText = JSON.stringify(data, null, " ")
    this.#shadowRoot.appendChild(pre)
  }

  fetchComments(postid) {
    const url = new URL(this.#basepath + this.#restComments)
    var params = {key: postid}
    url.search = new URLSearchParams(params).toString()

    this.#boot.secureFetch(url).then(reply => {
      if(reply.status !== 200) throw "status=" + reply.status
      return reply.json()

    }).then(data => {
      this.renderComments(postid, data)

    }).catch(err => console.error(`Unable to fetch comments for post ${postid}. ` + err))
  }

  renderComments(postid, comments) {
    var li = this.#shadowRoot.getElementById(postid)
    var cul = document.createElement('ul')
    cul.classList.add('d4s-post-comments')
    comments.result.forEach(comment => {
      var cli = document.createElement('li')
      cli.id = comment.feedid
      cli.classList.add('d4s-post-comment')
      const thumbnail = (!comment.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + comment.thumbnail_url : comment.thumbnail_url
      const datetime = new Date(0)
      datetime.setUTCMilliseconds(comment.time)
      const datetimestr = datetime.toLocaleString([], {year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit'})
      cli.innerHTML = `
        <div class="d4s-comment-avatar">
          <img src="${thumbnail}" onerror="this.style.display='none'"></slot>
        </div>
        <div class="d4s-comment">
          <div class="d4s-comment-body">
            <div class="fullname">${comment.full_name}</div>
            <div class="d4s-comment-text">${comment.text}</div>
          </div>
          <div class="d4s-comment-footer">
            <div class="time">${datetimestr}</div>
          </div>
        </div>
      `
      cul.appendChild(cli)
    })
    li.appendChild(cul)
  }

  static get observedAttributes() {
    return ["url", "from", "quantity"];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (oldValue !== newValue) {
      switch (name) {
        case "url":
          this.#basepath = newValue
          break
        case "from":
          this.#from = Number(newValue)
          break
        case "quantity":
          this.#quantity = Number(newValue)
          break
      }
    }
  }
  
  get url() {
    return this.#basepath
  }

  set url(url) {
    this.#basepath = url
    this.setAttribute("url", url)
  }

  get from() {
    return this.#from
  }

  set from(from) {
    this.#from = Number(from)
    this.setAttribute("from", from)
  }

  get quantity() {
    return this.#quantity
  }

  set quantity(quantity) {
    this.#quantity = Number(quantity)
    this.setAttribute("quantity", quantity)
  }
});