package dev.inmo.plaguposter.posts import dev.inmo.kslog.common.logger import dev.inmo.kslog.common.w import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.repos.deleteById import dev.inmo.plagubot.Plugin import dev.inmo.plaguposter.common.SuccessfulSymbol import dev.inmo.plaguposter.common.UnsuccessfulSymbol import dev.inmo.plaguposter.posts.exposed.ExposedPostsRepo import dev.inmo.plaguposter.common.ChatConfig import dev.inmo.plaguposter.inlines.models.Format import dev.inmo.plaguposter.inlines.models.OfferTemplate import dev.inmo.plaguposter.inlines.repos.InlineTemplatesRepo import dev.inmo.plaguposter.posts.repo.* import dev.inmo.plaguposter.posts.sending.PostPublisher import dev.inmo.tgbotapi.extensions.api.delete import dev.inmo.tgbotapi.extensions.api.edit.edit import dev.inmo.tgbotapi.extensions.api.send.reply import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand import dev.inmo.tgbotapi.types.message.textsources.regular import kotlinx.serialization.Serializable import kotlinx.serialization.json.* import org.jetbrains.exposed.sql.Database import org.koin.core.Koin import org.koin.core.module.Module import org.koin.dsl.binds object Plugin : Plugin { @Serializable data class Config( val chats: ChatConfig, val autoRemoveMessages: Boolean = true, val deleteAfterPublishing: Boolean = true ) override fun Module.setupDI(database: Database, params: JsonObject) { val configJson = params["posts"] ?: this@Plugin.let { it.logger.w { "Unable to load posts plugin due to absence of `posts` key in config" } return } single { get().decodeFromJsonElement(Config.serializer(), configJson) } single { get().chats } single { ExposedPostsRepo(database) } binds arrayOf( PostsRepo::class, ReadPostsRepo::class, WritePostsRepo::class, ) single { val config = get() PostPublisher(get(), get(), config.chats.cacheChatId, config.chats.targetChatId, config.deleteAfterPublishing) } } override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { val postsRepo = koin.get() val config = koin.get() if (config.autoRemoveMessages) { postsRepo.removedPostsFlow.subscribeSafelyWithoutExceptions(this) { it.content.forEach { runCatchingSafely { delete(it.chatId, it.messageId) } } } } onCommand("delete_post", requireOnlyCommandInMessage = true) { val messageInReply = it.replyTo ?: run { reply(it, "Reply some message of post to delete it") return@onCommand } val postId = postsRepo.getIdByChatAndMessage(messageInReply.chat.id, messageInReply.messageId) ?: run { reply(it, "Unable to find post id by message") return@onCommand } postsRepo.deleteById(postId) if (postsRepo.contains(postId)) { edit(it, it.content.textSources + regular(UnsuccessfulSymbol)) } else { edit(it, it.content.textSources + regular(SuccessfulSymbol)) } } koin.getOrNull() ?.addTemplate( OfferTemplate( "Delete post", listOf( Format("/delete_post") ) ) ) } }