package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow import dev.inmo.tgbotapi.extensions.utils.asBaseSentMessageUpdate import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage internal suspend inline fun BehaviourContext.onEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, noinline additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, noinline scenarioReceiver: BehaviourContextAndTypeReceiver> ) = flowsUpdatesFilter.expectFlow(bot) { it.asBaseSentMessageUpdate() ?.data ?.asChatEventMessage() ?.let { message -> if (message.chatEvent is T) { val adaptedMessage = message as ChatEventMessage if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null } else { null } }.let(::listOfNotNull) }.subscribeSafelyWithoutExceptions(scope) { triggerMessage -> doInSubContextWithUpdatesFilter( updatesFilter = if (includeFilterByChatInBehaviourSubContext) { { it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId } } else null, stopOnCompletion = false ) { scenarioReceiver(triggerMessage) } } suspend fun BehaviourContext.onChannelEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onChatEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVoiceChatEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVoiceChatStartedEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVoiceChatEndedEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVoiceChatParticipantsInvitedEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onMessageAutoDeleteTimerChangedEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onCommonEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onGroupEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onSupergroupEvent( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onChannelChatCreated( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onDeleteChatPhoto( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onGroupChatCreated( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onLeftChatMember( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onNewChatMembers( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onNewChatPhoto( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onNewChatTitle( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onPinnedMessage( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onProximityAlertTriggered( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onSupergroupChatCreated( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: (suspend (ChatEventMessage) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)