@file:Suppress("unused", "UNCHECKED_CAST") package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptionsAsync import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.types.message.content.media.* import dev.inmo.tgbotapi.types.message.payments.InvoiceContent import dev.inmo.tgbotapi.utils.PreviewFeature typealias CommonMessageFilter = (suspend (CommonMessage) -> Boolean) @PreviewFeature internal suspend inline fun BehaviourContext.onContent( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = true, noinline additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, noinline scenarioReceiver: BehaviourContextAndTypeReceiver> ) = flowsUpdatesFilter.expectFlow(bot) { val messages = it.whenBaseSentMessageUpdate { it.data.whenCommonMessage(::listOfNotNull) } ?: if (includeMediaGroups) { it.asSentMediaGroupUpdate() ?.data ?: emptyList() } else { emptyList() } messages.mapNotNull { message -> if (message.content is T) { val adaptedMessage = message as CommonMessage if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null } else { null } } }.subscribeSafelyWithoutExceptionsAsync( scope, markerFactory::invoke ) { triggerMessage -> doInSubContextWithUpdatesFilter( updatesFilter = if (includeFilterByChatInBehaviourSubContext) { { it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId } } else { null }, stopOnCompletion = false ) { scenarioReceiver(triggerMessage) } } suspend fun BehaviourContext.onContentMessage( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, includeMediaGroups: Boolean = true, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onContact( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onDice( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onGame( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onLocation( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onPoll( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onText( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onVenue( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onAudioMediaGroup( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onDocumentMediaGroupContent( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onMediaCollection( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: (suspend (CommonMessage>) -> Boolean)? = null, markerFactory: MarkerFactory>, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver>> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onMedia( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onAnimation( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onAudio( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onDocument( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onPhoto( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onSticker( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onVideo( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onVideoNote( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onVoice( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver) suspend fun BehaviourContext.onInvoice( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, markerFactory, scenarioReceiver)