package com.github.twitch4j.chat.events.channel;

import com.github.twitch4j.chat.events.AbstractChannelEvent;
import com.github.twitch4j.chat.flag.AutoModFlag;
import com.github.twitch4j.common.annotation.Unofficial;
import com.github.twitch4j.common.enums.CommandPermission;
import com.github.twitch4j.common.events.domain.EventChannel;
import com.github.twitch4j.common.events.domain.EventUser;
import com.github.twitch4j.common.util.ChatReply;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Value;

import java.util.List;
import java.util.Set;

/**
 * This event gets called when a message is received in a channel.
 */
@Value
@Getter
@EqualsAndHashCode(callSuper = false)
public class ChannelMessageEvent extends AbstractChannelEvent {

    /**
     * RAW Message Event
     */
    private final IRCMessageEvent messageEvent;

	/**
	 * User
	 */
	private EventUser user;

	/**
	 * Message
	 */
	private String message;

	/**
	 * Permissions of the user
	 */
	private Set<CommandPermission> permissions;

    /**
     * The exact number of months the user has been a subscriber, or zero if not subscribed
     */
	private int subscriberMonths;

    /**
     * The tier at which the user is subscribed (prime is treated as 1), or zero if not subscribed
     */
	private int subscriptionTier;

    /**
     * Nonce
     */
    @Unofficial
    @Getter(lazy = true)
    private String nonce = getMessageEvent().getNonce().orElse(null);

    /**
     * Information regarding the parent message being replied to, if applicable.
     */
    @Unofficial
    @Getter(lazy = true)
    private ChatReply replyInfo = ChatReply.parse(getMessageEvent().getTags());

	/**
	 * Event Constructor
	 *
	 * @param channel     The channel that this event originates from.
     * @param messageEvent The raw message event
	 * @param user        The user who triggered the event.
	 * @param message     The plain text of the message.
	 * @param permissions The permissions of the triggering user.
	 */
	public ChannelMessageEvent(EventChannel channel, IRCMessageEvent messageEvent, EventUser user, String message, Set<CommandPermission> permissions) {
		super(channel);
        this.messageEvent = messageEvent;
		this.user = user;
		this.message = message;
		this.permissions = permissions;
		this.subscriberMonths = messageEvent.getSubscriberMonths().orElse(0);
		this.subscriptionTier = messageEvent.getSubscriptionTier().orElse(0);
	}

    /**
     * @return the regions of the message that were flagged by AutoMod.
     */
    @Unofficial
    public List<AutoModFlag> getFlags() {
        return this.messageEvent.getFlags();
    }
}

@@ -541,16 +541,43 @@
 l.List;%0A
+import java.util.Optional;%0A
 import j
@@ -2463,16 +2463,791 @@
 0);%0A%09%7D%0A%0A
+    /**%0A     * @return whether %22Highlight My Message%22 was redeemed for this event%0A     */%0A    @Unofficial%0A    public boolean isHighlightedMessage() %7B%0A        return %22highlighted-message%22.equals(getMessageEvent().getTags().get(%22msg-id%22));%0A    %7D%0A%0A    /**%0A     * @return whether %22Send a Message in Sub-Only Mode%22 was redeemed for this event%0A     */%0A    @Unofficial%0A    public boolean isSkipSubsModeMessage() %7B%0A        return %22skip-subs-mode-message%22.equals(getMessageEvent().getTags().get(%22msg-id%22));%0A    %7D%0A%0A    /**%0A     * @return the id for the custom reward that was redeemed with this associated message, in an optional wrapper%0A     */%0A    @Unofficial%0A    public Optional%3CString%3E getCustomRewardId() %7B%0A        return getMessageEvent().getTagValue(%22custom-reward-id%22);%0A    %7D%0A%0A
     /**%0A

add convenience methods for chat-based redemptions