package jp.juggler.subwaytooter

import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.os.SystemClock
import android.text.Spannable
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.annotation.StringRes
import jp.juggler.subwaytooter.api.TootParser
import jp.juggler.subwaytooter.api.entity.*
import jp.juggler.subwaytooter.drawable.PreviewCardBorder
import jp.juggler.subwaytooter.span.MyClickableSpan
import jp.juggler.subwaytooter.table.*
import jp.juggler.subwaytooter.util.Benchmark
import jp.juggler.subwaytooter.util.DecodeOptions
import jp.juggler.subwaytooter.view.CountImageButton
import jp.juggler.subwaytooter.view.MyNetworkImageView
import jp.juggler.util.*
import org.jetbrains.anko.backgroundColor
import org.jetbrains.anko.textColor
import kotlin.math.max

@SuppressLint("ClickableViewAccessibility")
fun ItemViewHolder.bind(
    listAdapter: ItemListAdapter,
    column: Column,
    bSimpleList: Boolean,
    item: TimelineItem,
) {
    val b = Benchmark(ItemViewHolder.log, "Item-bind", 40L)

    this.listAdapter = listAdapter
    this.column = column
    this.bSimpleList = bSimpleList

    this.accessInfo = column.accessInfo

    val fontBold = ActMain.timeline_font_bold
    val fontNormal = ActMain.timelineFont
    viewRoot.scan { v ->
        try {
            when (v) {
                // ボタンは太字なので触らない
                is CountImageButton -> {
                }
                // ボタンは太字なので触らない
                is Button -> {
                }

                is TextView -> v.typeface = when {
                    v === tvName ||
                        v === tvFollowerName ||
                        v === tvBoosted ||
                        v === tvReply ||
                        v === tvTrendTagCount ||
                        v === tvTrendTagName ||
                        v === tvConversationIconsMore ||
                        v === tvConversationParticipants ||
                        v === tvFilterPhrase -> fontBold
                    else -> fontNormal
                }
            }
        } catch (ex: Throwable) {
            ItemViewHolder.log.trace(ex)
        }
    }

    if (bSimpleList) {

        viewRoot.setOnTouchListener { _, ev ->
            // ポップアップを閉じた時にクリックでリストを触ったことになってしまう不具合の回避
            val now = SystemClock.elapsedRealtime()
            // ポップアップを閉じた直後はタッチダウンを無視する
            if (now - StatusButtonsPopup.lastPopupClose >= 30L) {
                false
            } else {
                val action = ev.action
                ItemViewHolder.log.d("onTouchEvent action=$action")
                true
            }
        }

        viewRoot.setOnClickListener { viewClicked ->
            activity.closeListItemPopup()
            statusShowing?.let { status ->
                val popup =
                    StatusButtonsPopup(activity, column, bSimpleList, this@bind)
                activity.listItemPopup = popup
                popup.show(
                    listAdapter.columnVh.listView,
                    viewClicked,
                    status,
                    item as? TootNotification
                )
            }
        }
        llButtonBar.visibility = View.GONE
        this.buttonsForStatus = null
    } else {
        viewRoot.isClickable = false
        llButtonBar.visibility = View.VISIBLE
        this.buttonsForStatus = StatusButtons(
            activity,
            column,
            false,
            statusButtonsViewHolder,
            this
        )
    }

    this.statusShowing = null
    this.statusReply = null
    this.statusAccount = null
    this.boostAccount = null
    this.followAccount = null
    this.boostTime = 0L
    this.viewRoot.setBackgroundColor(0)
    this.boostedAction = defaultBoostedAction

    llOpenSticker.visibility = View.GONE
    llBoosted.visibility = View.GONE
    llReply.visibility = View.GONE
    llFollow.visibility = View.GONE
    llStatus.visibility = View.GONE
    llSearchTag.visibility = View.GONE
    btnGapHead.visibility = View.GONE
    btnGapTail.visibility = View.GONE
    llList.visibility = View.GONE
    llFollowRequest.visibility = View.GONE
    tvMessageHolder.visibility = View.GONE
    llTrendTag.visibility = View.GONE
    llFilter.visibility = View.GONE
    tvMediaDescription.visibility = View.GONE
    llCardOuter.visibility = View.GONE
    tvCardText.visibility = View.GONE
    flCardImage.visibility = View.GONE
    llConversationIcons.visibility = View.GONE

    removeExtraView()

    var c: Int
    c = column.getContentColor()
    this.contentColor = c
    this.contentColorCsl = ColorStateList.valueOf(c)

    tvBoosted.setTextColor(c)
    tvReply.setTextColor(c)
    tvFollowerName.setTextColor(c)
    tvName.setTextColor(c)
    tvMentions.setTextColor(c)
    tvContentWarning.setTextColor(c)
    tvContent.setTextColor(c)
    //NSFWは文字色固定 btnShowMedia.setTextColor( c );
    tvApplication.setTextColor(c)
    tvMessageHolder.setTextColor(c)
    tvTrendTagName.setTextColor(c)
    tvTrendTagCount.setTextColor(c)
    cvTagHistory.setColor(c)
    tvFilterPhrase.setTextColor(c)
    tvMediaDescription.setTextColor(c)
    tvCardText.setTextColor(c)
    tvConversationIconsMore.setTextColor(c)
    tvConversationParticipants.setTextColor(c)

    (llCardOuter.background as? PreviewCardBorder)?.let {
        val rgb = c and 0xffffff
        val alpha = max(1, c ushr (24 + 1)) // 本来の値の半分にする
        it.color = rgb or (alpha shl 24)
    }

    c = column.getAcctColor()
    this.acctColor = c
    tvBoostedTime.setTextColor(c)
    tvTime.setTextColor(c)
    tvTrendTagDesc.setTextColor(c)
    tvFilterDetail.setTextColor(c)
    tvFilterPhrase.setTextColor(c)

    // 以下のビューの文字色はsetAcct() で設定される
    //		tvBoostedAcct.setTextColor(c)
    //		tvFollowerAcct.setTextColor(c)
    //		tvAcct.setTextColor(c)

    this.item = item
    when (item) {
        is TootStatus -> {
            val reblog = item.reblog
            when {
                reblog == null -> showStatusOrReply(item)

                item.isQuoteToot -> {
                    // 引用Renote
                    val colorBg = PrefI.ipEventBgColorBoost(activity.pref)
                    showReply(reblog, R.drawable.ic_repeat, R.string.quote_to)
                    showStatus(item, colorBg)
                }

                else -> {
                    // 引用なしブースト
                    val colorBg = PrefI.ipEventBgColorBoost(activity.pref)
                    showBoost(
                        item.accountRef,
                        item.time_created_at,
                        R.drawable.ic_repeat,
                        R.string.display_name_boosted_by,
                        boostStatus = item
                    )
                    showStatusOrReply(item.reblog, colorBg)
                }
            }
        }

        is TootAccountRef -> showAccount(item)
        is TootNotification -> showNotification(item)
        is TootGap -> showGap()
        is TootSearchGap -> showSearchGap(item)
        is TootDomainBlock -> showDomainBlock(item)
        is TootList -> showList(item)
        is MisskeyAntenna -> showAntenna(item)
        is TootMessageHolder -> showMessageHolder(item)
        is TootTag -> showSearchTag(item)
        is TootFilter -> showFilter(item)
        is TootConversationSummary -> {
            showStatusOrReply(item.last_status)
            showConversationIcons(item)
        }
        is TootScheduled -> showScheduled(item)
    }
    b.report()
}

fun ItemViewHolder.removeExtraView() {
    llExtra.scan { v ->
        if (v is MyNetworkImageView) {
            v.cancelLoading()
        }
    }
    llExtra.removeAllViews()

    for (invalidator in extraInvalidatorList) {
        invalidator.register(null)
    }
    extraInvalidatorList.clear()
}

fun ItemViewHolder.showAccount(whoRef: TootAccountRef) {

    followAccount = whoRef
    val who = whoRef.get()
    llFollow.visibility = View.VISIBLE
    ivFollow.setImageUrl(
        activity.pref,
        Styler.calcIconRound(ivFollow.layoutParams),
        accessInfo.supplyBaseUrl(who.avatar_static),
        accessInfo.supplyBaseUrl(who.avatar)
    )

    tvFollowerName.text = whoRef.decoded_display_name
    followInvalidator.register(whoRef.decoded_display_name)

    setAcct(tvFollowerAcct, accessInfo, who)

    who.setAccountExtra(
        accessInfo,
        tvLastStatusAt,
        lastActiveInvalidator,
        suggestionSource = if (column.type == ColumnType.FOLLOW_SUGGESTION) {
            SuggestionSource.get(accessInfo.db_id, who.acct)
        } else {
            null
        }
    )

    val relation = UserRelation.load(accessInfo.db_id, who.id)
    Styler.setFollowIcon(
        activity,
        btnFollow,
        ivFollowedBy,
        relation,
        who,
        contentColor,
        alphaMultiplier = Styler.boostAlpha
    )

    if (column.type == ColumnType.FOLLOW_REQUESTS) {
        llFollowRequest.visibility = View.VISIBLE
        btnFollowRequestAccept.imageTintList = contentColorCsl
        btnFollowRequestDeny.imageTintList = contentColorCsl
    }
}

fun ItemViewHolder.showAntenna(a: MisskeyAntenna) {
    llList.visibility = View.VISIBLE
    btnListTL.text = a.name
    btnListTL.textColor = contentColor
    btnListMore.imageTintList = contentColorCsl
}

fun ItemViewHolder.showBoost(
    whoRef: TootAccountRef,
    time: Long,
    iconId: Int,
    @StringRes stringId: Int,
    reaction: TootReaction? = null,
    boostStatus: TootStatus? = null,
) {
    boostAccount = whoRef

    setIconDrawableId(
        activity,
        ivBoosted,
        iconId,
        color = contentColor,
        alphaMultiplier = Styler.boostAlpha
    )

    val who = whoRef.get()

    // フォローの場合 decoded_display_name が2箇所で表示に使われるのを避ける必要がある
    val text: Spannable = if (reaction != null) {
        val options = DecodeOptions(
            activity,
            accessInfo,
            decodeEmoji = true,
            enlargeEmoji = 1.5f,
            enlargeCustomEmoji = 1.5f
        )
        val ssb = reaction.toSpannableStringBuilder(options, boostStatus)
        ssb.append(" ")
        ssb.append(
            who.decodeDisplayName(activity)
                .intoStringResource(activity, stringId)
        )
    } else {
        who.decodeDisplayName(activity)
            .intoStringResource(activity, stringId)
    }

    boostTime = time
    llBoosted.visibility = View.VISIBLE
    showStatusTime(activity, tvBoostedTime, who, time = time, status = boostStatus)
    tvBoosted.text = text
    boostInvalidator.register(text)
    setAcct(tvBoostedAcct, accessInfo, who)
}

fun ItemViewHolder.showMessageHolder(item: TootMessageHolder) {
    tvMessageHolder.visibility = View.VISIBLE
    tvMessageHolder.text = item.text
    tvMessageHolder.gravity = item.gravity
}

fun ItemViewHolder.showList(list: TootList) {
    llList.visibility = View.VISIBLE
    btnListTL.text = list.title
    btnListTL.textColor = contentColor
    btnListMore.imageTintList = contentColorCsl
}

fun ItemViewHolder.showDomainBlock(domainBlock: TootDomainBlock) {
    llSearchTag.visibility = View.VISIBLE
    btnSearchTag.text = domainBlock.domain.pretty
}

fun ItemViewHolder.showFilter(filter: TootFilter) {
    llFilter.visibility = View.VISIBLE
    tvFilterPhrase.text = filter.phrase

    val sb = StringBuffer()
    //
    sb.append(activity.getString(R.string.filter_context))
        .append(": ")
        .append(filter.getContextNames(activity).joinToString("/"))
    //
    val flags = ArrayList<String>()
    if (filter.irreversible) flags.add(activity.getString(R.string.filter_irreversible))
    if (filter.whole_word) flags.add(activity.getString(R.string.filter_word_match))
    if (flags.isNotEmpty()) {
        sb.append('\n')
            .append(flags.joinToString(", "))
    }
    //
    if (filter.time_expires_at != 0L) {
        sb.append('\n')
            .append(activity.getString(R.string.filter_expires_at))
            .append(": ")
            .append(TootStatus.formatTime(activity, filter.time_expires_at, false))
    }

    tvFilterDetail.text = sb.toString()
}

fun ItemViewHolder.showSearchTag(tag: TootTag) {
    if (tag.history?.isNotEmpty() == true) {
        llTrendTag.visibility = View.VISIBLE
        tvTrendTagName.text = "#${tag.name}"
        tvTrendTagDesc.text =
            activity.getString(R.string.people_talking, tag.accountDaily, tag.accountWeekly)
        tvTrendTagCount.text = "${tag.countDaily}(${tag.countWeekly})"
        cvTagHistory.setHistory(tag.history)
    } else {
        llSearchTag.visibility = View.VISIBLE
        btnSearchTag.text = "#" + tag.name
    }
}

fun ItemViewHolder.showGap() {
    llSearchTag.visibility = View.VISIBLE
    btnSearchTag.text = activity.getString(R.string.read_gap)

    btnGapHead.vg(column.type.gapDirection(column, true))
        ?.imageTintList = contentColorCsl

    btnGapTail.vg(column.type.gapDirection(column, false))
        ?.imageTintList = contentColorCsl

    val c = PrefI.ipEventBgColorGap(App1.pref)
    if (c != 0) this.viewRoot.backgroundColor = c
}

fun ItemViewHolder.showSearchGap(item: TootSearchGap) {
    llSearchTag.visibility = View.VISIBLE
    btnSearchTag.text = activity.getString(
        when (item.type) {
            TootSearchGap.SearchType.Hashtag -> R.string.read_more_hashtag
            TootSearchGap.SearchType.Account -> R.string.read_more_account
            TootSearchGap.SearchType.Status -> R.string.read_more_status
        }
    )
}

fun ItemViewHolder.showReply(iconId: Int, text: Spannable) {

    llReply.visibility = View.VISIBLE

    setIconDrawableId(
        activity,
        ivReply,
        iconId,
        color = contentColor,
        alphaMultiplier = Styler.boostAlpha
    )

    tvReply.text = text
    replyInvalidator.register(text)
}

fun ItemViewHolder.showReply(reply: TootStatus, iconId: Int, stringId: Int) {
    statusReply = reply
    showReply(
        iconId,
        reply.accountRef.decoded_display_name.intoStringResource(activity, stringId)
    )
}

fun ItemViewHolder.showReply(reply: TootStatus, accountId: EntityId) {
    val name = if (accountId == reply.account.id) {
        // 自己レスなら
        AcctColor.getNicknameWithColor(accessInfo, reply.account)
    } else {
        val m = reply.mentions?.find { it.id == accountId }
        if (m != null) {
            AcctColor.getNicknameWithColor(accessInfo.getFullAcct(m.acct))
        } else {
            SpannableString("ID($accountId)")
        }
    }

    val text = name.intoStringResource(activity, R.string.reply_to)
    showReply(R.drawable.ic_reply, text)

    // tootsearchはreplyオブジェクトがなくin_reply_toだけが提供される場合があるが
    // tootsearchではどのタンスから読んだか分からないのでin_reply_toのIDも信用できない
}

fun ItemViewHolder.showStatusTime(
    activity: ActMain,
    tv: TextView,
    @Suppress("UNUSED_PARAMETER") who: TootAccount,
    status: TootStatus? = null,
    time: Long? = null,
) {
    val sb = SpannableStringBuilder()

    if (status != null) {

        if (status.account.isAdmin) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_shield, "admin")
        }

        if (status.account.isPro) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_authorized, "pro")
        }

        if (status.account.isCat) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_cat, "cat")
        }

        // botマーク
        if (status.account.bot) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_bot, "bot")
        }

        if (status.account.suspended) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_delete, "suspended")
        }

        // mobileマーク
        if (status.viaMobile) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_mobile, "mobile")
        }

        // mobileマーク
        if (status.bookmarked) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_bookmark, "bookmarked")
        }

        // NSFWマーク
        if (status.hasMedia() && status.sensitive) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_eye_off, "NSFW")
        }

        // visibility
        val visIconId =
            Styler.getVisibilityIconId(accessInfo.isMisskey, status.visibility)
        if (R.drawable.ic_public != visIconId) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(
                activity,
                visIconId,
                Styler.getVisibilityString(
                    activity,
                    accessInfo.isMisskey,
                    status.visibility
                )
            )
        }

        // pinned
        if (status.pinned) {
            if (sb.isNotEmpty()) sb.append('\u200B')
            sb.appendColorShadeIcon(activity, R.drawable.ic_pin, "pinned")

            //				val start = sb.length
            //				sb.append("pinned")
            //				val end = sb.length
            //				val icon_id = Styler.getAttributeResourceId(activity, R.attr.ic_pin)
            //				sb.setSpan(
            //					EmojiImageSpan(activity, icon_id),
            //					start,
            //					end,
            //					Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            //				)
        }

        // unread
        if (status.conversationSummary?.unread == true) {
            if (sb.isNotEmpty()) sb.append('\u200B')

            sb.appendColorShadeIcon(
                activity,
                R.drawable.ic_unread,
                "unread",
                color = MyClickableSpan.defaultLinkColor
            )
        }

        if (status.isPromoted) {
            if (sb.isNotEmpty()) sb.append(' ')
            sb.append(activity.getString(R.string.promoted))
        }

        if (status.isFeatured) {
            if (sb.isNotEmpty()) sb.append(' ')
            sb.append(activity.getString(R.string.featured))
        }
    }

    if (sb.isNotEmpty()) sb.append(' ')
    sb.append(
        when {
            time != null -> TootStatus.formatTime(
                activity,
                time,
                column.type != ColumnType.CONVERSATION
            )
            status != null -> TootStatus.formatTime(
                activity,
                status.time_created_at,
                column.type != ColumnType.CONVERSATION
            )
            else -> "?"
        }
    )

    tv.text = sb
}

fun ItemViewHolder.showStatusTimeScheduled(
    activity: ActMain,
    tv: TextView,
    item: TootScheduled,
) {
    val sb = SpannableStringBuilder()

    // NSFWマーク
    if (item.hasMedia() && item.sensitive) {
        if (sb.isNotEmpty()) sb.append('\u200B')
        sb.appendColorShadeIcon(activity, R.drawable.ic_eye_off, "NSFW")
    }

    // visibility
    val visIconId =
        Styler.getVisibilityIconId(accessInfo.isMisskey, item.visibility)
    if (R.drawable.ic_public != visIconId) {
        if (sb.isNotEmpty()) sb.append('\u200B')
        sb.appendColorShadeIcon(
            activity,
            visIconId,
            Styler.getVisibilityString(
                activity,
                accessInfo.isMisskey,
                item.visibility
            )
        )
    }

    if (sb.isNotEmpty()) sb.append(' ')
    sb.append(
        TootStatus.formatTime(
            activity,
            item.timeScheduledAt,
            column.type != ColumnType.CONVERSATION
        )
    )

    tv.text = sb
}
//	fun updateRelativeTime() {
//		val boost_time = this.boost_time
//		if(boost_time != 0L) {
//			tvBoostedTime.text = TootStatus.formatTime(tvBoostedTime.context, boost_time, true)
//		}
//		val status_showing = this.status_showing
//		if(status_showing != null) {
//			showStatusTime(activity, status_showing)
//		}
//	}

fun ItemViewHolder.showScheduled(item: TootScheduled) {
    try {

        llStatus.visibility = View.VISIBLE

        this.viewRoot.setBackgroundColor(0)

        showStatusTimeScheduled(activity, tvTime, item)

        val who = column.whoAccount!!.get()
        val whoRef = TootAccountRef(TootParser(activity, accessInfo), who)
        this.statusAccount = whoRef

        setAcct(tvAcct, accessInfo, who)

        tvName.text = whoRef.decoded_display_name
        nameInvalidator.register(whoRef.decoded_display_name)
        ivAvatar.setImageUrl(
            activity.pref,
            Styler.calcIconRound(ivAvatar.layoutParams),
            accessInfo.supplyBaseUrl(who.avatar_static),
            accessInfo.supplyBaseUrl(who.avatar)
        )

        val content = SpannableString(item.text ?: "")

        tvMentions.visibility = View.GONE

        tvContent.text = content
        contentInvalidator.register(content)

        tvContent.minLines = -1

        val decodedSpoilerText = SpannableString(item.spoilerText ?: "")
        when {
            decodedSpoilerText.isNotEmpty() -> {
                // 元データに含まれるContent Warning を使う
                llContentWarning.visibility = View.VISIBLE
                tvContentWarning.text = decodedSpoilerText
                spoilerInvalidator.register(decodedSpoilerText)
                val cwShown = ContentWarning.isShown(item.uri, accessInfo.expand_cw)
                showContent(cwShown)
            }

            else -> {
                // CWしない
                llContentWarning.visibility = View.GONE
                llContents.visibility = View.VISIBLE
            }
        }

        val mediaAttachments = item.mediaAttachments
        if (mediaAttachments?.isEmpty() != false) {
            flMedia.visibility = View.GONE
            llMedia.visibility = View.GONE
            btnShowMedia.visibility = View.GONE
        } else {
            flMedia.visibility = View.VISIBLE

            // hide sensitive media
            val defaultShown = when {
                column.hideMediaDefault -> false
                accessInfo.dont_hide_nsfw -> true
                else -> !item.sensitive
            }
            val isShown = MediaShown.isShown(item.uri, defaultShown)

            btnShowMedia.visibility = if (!isShown) View.VISIBLE else View.GONE
            llMedia.visibility = if (!isShown) View.GONE else View.VISIBLE
            val sb = StringBuilder()
            setMedia(mediaAttachments, sb, ivMedia1, 0)
            setMedia(mediaAttachments, sb, ivMedia2, 1)
            setMedia(mediaAttachments, sb, ivMedia3, 2)
            setMedia(mediaAttachments, sb, ivMedia4, 3)
            if (sb.isNotEmpty()) {
                tvMediaDescription.visibility = View.VISIBLE
                tvMediaDescription.text = sb
            }

            setIconDrawableId(
                activity,
                btnHideMedia,
                R.drawable.ic_close,
                color = contentColor,
                alphaMultiplier = Styler.boostAlpha
            )
        }

        buttonsForStatus?.hide()

        tvApplication.visibility = View.GONE
    } catch (ex: Throwable) {
        ItemViewHolder.log.w(ex, "showScheduled failed")
    }
    llSearchTag.visibility = View.VISIBLE
    btnSearchTag.text = activity.getString(R.string.scheduled_status) + " " +
        TootStatus.formatTime(activity, item.timeScheduledAt, true)
}

fun ItemViewHolder.showConversationIcons(cs: TootConversationSummary) {

    val lastAccountId = cs.last_status.account.id

    val accountsOther = cs.accounts.filter { it.get().id != lastAccountId }
    if (accountsOther.isNotEmpty()) {
        llConversationIcons.visibility = View.VISIBLE

        val size = accountsOther.size

        tvConversationParticipants.text = if (size <= 1) {
            activity.getString(R.string.conversation_to)
        } else {
            activity.getString(R.string.participants)
        }

        fun showIcon(iv: MyNetworkImageView, idx: Int) {
            val bShown = idx < size
            iv.visibility = if (bShown) View.VISIBLE else View.GONE
            if (!bShown) return

            val who = accountsOther[idx].get()
            iv.setImageUrl(
                activity.pref,
                Styler.calcIconRound(iv.layoutParams),
                accessInfo.supplyBaseUrl(who.avatar_static),
                accessInfo.supplyBaseUrl(who.avatar)
            )
        }
        showIcon(ivConversationIcon1, 0)
        showIcon(ivConversationIcon2, 1)
        showIcon(ivConversationIcon3, 2)
        showIcon(ivConversationIcon4, 3)

        tvConversationIconsMore.text = when {
            size <= 4 -> ""
            else -> activity.getString(R.string.participants_and_more)
        }
    }

    if (cs.last_status.in_reply_to_id != null) {
        llSearchTag.visibility = View.VISIBLE
        btnSearchTag.text = activity.getString(R.string.show_conversation)
    }
}

fun ItemViewHolder.setAcct(tv: TextView, accessInfo: SavedAccount, who: TootAccount) {
    val ac = AcctColor.load(accessInfo, who)
    tv.text = when {
        AcctColor.hasNickname(ac) -> ac.nickname
        PrefB.bpShortAcctLocalUser(App1.pref) -> "@${who.acct.pretty}"
        else -> "@${ac.nickname}"
    }
    tv.textColor = ac.color_fg.notZero() ?: this.acctColor

    tv.setBackgroundColor(ac.color_bg) // may 0
    tv.setPaddingRelative(activity.acctPadLr, 0, activity.acctPadLr, 0)
}
