# SPDX-License-Identifier: AGPL-3.0-only
import sequtils
import karax/[karaxdsl, vdom]

import ".."/[types, formatters]
import tweet, timeline

proc renderEarlier(thread: Chain): VNode =
  buildHtml(tdiv(class="timeline-item more-replies earlier-replies")):
    a(class="more-replies-text", href=getLink(thread.content[0])):
      text "earlier replies"

proc renderMoreReplies(thread: Chain): VNode =
  let link = getLink(thread.content[^1])
  buildHtml(tdiv(class="timeline-item more-replies")):
    if thread.content[^1].available:
      a(class="more-replies-text", href=link):
        text "more replies"
    else:
      a(class="more-replies-text"):
        text "more replies"

proc renderReplyThread(thread: Chain; prefs: Prefs; path: string): VNode =
  buildHtml(tdiv(class="reply thread thread-line")):
    for i, tweet in thread.content:
      let last = (i == thread.content.high and not thread.hasMore)
      renderTweet(tweet, prefs, path, index=i, last=last)

    if thread.hasMore:
      renderMoreReplies(thread)

proc renderReplySort(sort: RankingMode): VNode =
  buildHtml(tdiv(class="reply-sort")):
    span(class="reply-sort-label"): text "Sort replies:"
    for mode in RankingMode:
      let
        cls = if mode == sort: "reply-sort-option active"
              else: "reply-sort-option"
        label = case mode
                of Relevance: "Relevant"
                of Recency: "Recent"
                of Likes: "Liked"
      a(class=cls, href=("?sort=" & $mode & "#r")):
        text label

proc renderReplies*(replies: Result[Chain]; prefs: Prefs; path: string;
                    tweet: Tweet = nil; sort = Relevance): VNode =
  buildHtml(tdiv(class="replies", id="r")):
    var hasReplies = false
    var replyCount = 0
    for thread in replies.content:
      if thread.content.len == 0 or thread.related: continue
      hasReplies = true
      replyCount += thread.content.len
      renderReplyThread(thread, prefs, path)

    if hasReplies and replies.bottom.len > 0:
      if tweet == nil or not replies.beginning or replyCount < tweet.stats.replies:
        let extra = if sort == Relevance: "" else: "sort=" & $sort & "&"
        renderMore(Query(), replies.bottom, focus="#r", extra=extra)

proc renderRelated(replies: Result[Chain]; prefs: Prefs; path: string): VNode =
  buildHtml(tdiv(class="related-tweets")):
    tdiv(class="related-header"):
      text "Related tweets"
    for thread in replies.content:
      if thread.content.len == 0 or not thread.related: continue
      renderReplyThread(thread, prefs, path)

proc renderConversation*(conv: Conversation; prefs: Prefs; path: string;
                         sort = Relevance): VNode =
  let hasAfter = conv.after.content.len > 0
  let threadId = conv.tweet.threadId
  buildHtml(tdiv(class="conversation")):
    tdiv(class="main-thread"):
      if conv.before.content.len > 0:
        tdiv(class="before-tweet thread-line"):
          let first = conv.before.content[0]
          if threadId != first.id and (first.replyId > 0 or not first.available):
            renderEarlier(conv.before)
          for i, tweet in conv.before.content:
            renderTweet(tweet, prefs, path, index=i)

      tdiv(class="main-tweet", id="m"):
        let afterClass = if hasAfter: "thread thread-line" else: ""
        renderTweet(conv.tweet, prefs, path, class=afterClass, mainTweet=true)

      if hasAfter:
        tdiv(class="after-tweet thread-line"):
          let
            total = conv.after.content.high
            hasMore = conv.after.hasMore
          for i, tweet in conv.after.content:
            renderTweet(tweet, prefs, path, index=i,
                        last=(i == total and not hasMore), afterTweet=true)

          if hasMore:
            renderMoreReplies(conv.after)

    if not prefs.hideReplies:
      if not conv.replies.beginning:
        renderNewer(Query(), getLink(conv.tweet), focus="#r")
      if conv.replies.content.len > 0 or conv.replies.bottom.len > 0:
        renderReplySort(sort)
        renderReplies(conv.replies, prefs, path, conv.tweet, sort)

    if not prefs.hideRelated:
      if conv.replies.content.anyIt(it.related and it.content.len > 0):
        renderRelated(conv.replies, prefs, path)

    renderToTop(focus="#m")

proc renderEditHistory*(edits: EditHistory; prefs: Prefs; path: string): VNode =
  buildHtml(tdiv(class="edit-history")):
    tdiv(class="latest-edit"):
      tdiv(class="edit-history-header"): 
        text "Latest post"
      renderTweet(edits.latest, prefs, path)

    tdiv(class="previous-edits"):
      tdiv(class="edit-history-header"): 
        text "Version history"
      for tweet in edits.history:
        tdiv(class="tweet-edit"):
          renderTweet(tweet, prefs, path)
