package com.vitorpamplona.amethyst.service

import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.model.RepostEvent
import com.vitorpamplona.amethyst.service.relays.FeedType
import com.vitorpamplona.amethyst.service.relays.TypedFilter
import nostr.postr.JsonFilter
import nostr.postr.events.TextNoteEvent
import nostr.postr.toHex

object NostrHomeDataSource: NostrDataSource<Note>("HomeFeed") {
  lateinit var account: Account

  object cacheListener: User.Listener() {
    override fun onFollowsChange() {
      resetFilters()
    }
  }

  override fun start() {
    if (this::account.isInitialized)
      account.userProfile().subscribe(cacheListener)
    super.start()
  }

  override fun stop() {
    super.stop()
    if (this::account.isInitialized)
      account.userProfile().unsubscribe(cacheListener)
  }

  fun createFollowAccountsFilter(): TypedFilter {
    val follows = account.userProfile().follows

    val followKeys = follows.map {
      it.pubkey.toHex().substring(0, 6)
    }

    val followSet = followKeys.plus(account.userProfile().pubkeyHex.substring(0, 6))

    return TypedFilter(
      types = setOf(FeedType.FOLLOWS),
      filter = JsonFilter(
        kinds = listOf(TextNoteEvent.kind, RepostEvent.kind),
        authors = followSet,
        limit = 400
      )
    )
  }

  val followAccountChannel = requestNewChannel()

  override fun feed(): List<Note> {
    val user = account.userProfile()

    return LocalCache.notes.values
      .filter { (it.event is TextNoteEvent || it.event is RepostEvent) && it.author in user.follows }
      .filter { account.isAcceptable(it) }
      .sortedBy { it.event?.createdAt }
      .reversed()
  }

  override fun updateChannelFilters() {
    followAccountChannel.typedFilters = listOf(createFollowAccountsFilter()).ifEmpty { null }
  }
}