// <auto-generated/>
// ReSharper disable All

namespace MyTelegram.Schema;

///<summary>
/// A message
/// See <a href="https://corefork.telegram.org/constructor/message" />
///</summary>
[TlObject(0x9815cec8)]
public sealed class TMessage : MyTelegram.Schema.IMessage, ILayeredMessage
{
    public uint ConstructorId => 0x9815cec8;
    ///<summary>
    /// Flags, see <a href="https://corefork.telegram.org/mtproto/TL-combinators#conditional-fields">TL conditional fields</a>
    ///</summary>
    public int Flags { get; set; }

    ///<summary>
    /// Is this an outgoing message
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Out { get; set; }

    ///<summary>
    /// Whether we were <a href="https://corefork.telegram.org/api/mentions">mentioned</a> in this message
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Mentioned { get; set; }

    ///<summary>
    /// Whether there are unread media attachments in this message
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool MediaUnread { get; set; }

    ///<summary>
    /// Whether this is a silent message (no notification triggered)
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Silent { get; set; }

    ///<summary>
    /// Whether this is a channel post
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Post { get; set; }

    ///<summary>
    /// Whether this is a <a href="https://corefork.telegram.org/api/scheduled-messages">scheduled message</a>
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool FromScheduled { get; set; }

    ///<summary>
    /// This is a legacy message: it has to be refetched with the new layer
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Legacy { get; set; }

    ///<summary>
    /// Whether the message should be shown as not modified to the user, even if an edit date is present
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool EditHide { get; set; }

    ///<summary>
    /// Whether this message is <a href="https://corefork.telegram.org/api/pin">pinned</a>
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Pinned { get; set; }

    ///<summary>
    /// Whether this message is <a href="https://telegram.org/blog/protected-content-delete-by-date-and-more">protected</a> and thus cannot be forwarded; clients should also prevent users from saving attached media (i.e. videos should only be streamed, photos should be kept in RAM, et cetera).
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Noforwards { get; set; }

    ///<summary>
    /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool InvertMedia { get; set; }

    ///<summary>
    /// Flags, see <a href="https://corefork.telegram.org/mtproto/TL-combinators#conditional-fields">TL conditional fields</a>
    ///</summary>
    public int Flags2 { get; set; }

    ///<summary>
    /// If set, the message was sent because of a scheduled action by the message sender, for example, as away, or a greeting service message.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool Offline { get; set; }

    ///<summary>
    /// The video contained in the message is currently being processed by the server (i.e. to generate alternative qualities, that will be contained in the final <a href="https://corefork.telegram.org/constructor/messageMediaDocument">messageMediaDocument</a>.<code>alt_document</code>), and will be sent once the video is processed, which will happen approximately at the specified <code>date</code> (i.e. messages with this flag set should be treated similarly to <a href="https://corefork.telegram.org/api/scheduled-messages">scheduled messages</a>, but instead of the scheduled date, <code>date</code> contains the estimated conversion date). <br>See <a href="https://corefork.telegram.org/api/files#video-qualities">here »</a> for more info.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool VideoProcessingPending { get; set; }
    public bool PaidSuggestedPostStars { get; set; }
    public bool PaidSuggestedPostTon { get; set; }

    ///<summary>
    /// ID of the message
    ///</summary>
    public int Id { get; set; }

    ///<summary>
    /// ID of the sender of the message
    /// See <a href="https://corefork.telegram.org/type/Peer" />
    ///</summary>
    public MyTelegram.Schema.IPeer? FromId { get; set; }

    ///<summary>
    /// Supergroups only, contains the number of <a href="https://corefork.telegram.org/api/boost">boosts</a> this user has given the current supergroup, and should be shown in the UI in the header of the message. <br>Only present for incoming messages from non-anonymous supergroup members that have boosted the supergroup. <br>Note that this counter should be locally overridden for non-anonymous <em>outgoing</em> messages, according to the current value of <a href="https://corefork.telegram.org/constructor/channelFull">channelFull</a>.<code>boosts_applied</code>, to ensure the value is correct even for messages sent by the current user before a supergroup was boosted (or after a boost has expired or the number of boosts has changed); do not update this value for incoming messages from other users, even if their boosts have changed.
    ///</summary>
    public int? FromBoostsApplied { get; set; }

    ///<summary>
    /// Peer ID, the chat where this message was sent
    /// See <a href="https://corefork.telegram.org/type/Peer" />
    ///</summary>
    public MyTelegram.Schema.IPeer PeerId { get; set; }

    ///<summary>
    /// Messages fetched from a <a href="https://corefork.telegram.org/api/saved-messages">saved messages dialog »</a> will have <code>peer</code>=<a href="https://corefork.telegram.org/constructor/inputPeerSelf">inputPeerSelf</a> and the <code>saved_peer_id</code> flag set to the ID of the saved dialog.<br>
    /// See <a href="https://corefork.telegram.org/type/Peer" />
    ///</summary>
    public MyTelegram.Schema.IPeer? SavedPeerId { get; set; }

    ///<summary>
    /// Info about forwarded messages
    /// See <a href="https://corefork.telegram.org/type/MessageFwdHeader" />
    ///</summary>
    public MyTelegram.Schema.IMessageFwdHeader? FwdFrom { get; set; }

    ///<summary>
    /// ID of the inline bot that generated the message
    ///</summary>
    public long? ViaBotId { get; set; }

    ///<summary>
    /// Whether the message was sent by the <a href="https://corefork.telegram.org/api/business#connected-bots">business bot</a> specified in <code>via_bot_id</code> on behalf of the user.
    ///</summary>
    public long? ViaBusinessBotId { get; set; }

    ///<summary>
    /// Reply information
    /// See <a href="https://corefork.telegram.org/type/MessageReplyHeader" />
    ///</summary>
    public MyTelegram.Schema.IMessageReplyHeader? ReplyTo { get; set; }

    ///<summary>
    /// Date of the message
    ///</summary>
    public int Date { get; set; }

    ///<summary>
    /// The message
    ///</summary>
    public string Message { get; set; }

    ///<summary>
    /// Media attachment
    /// See <a href="https://corefork.telegram.org/type/MessageMedia" />
    ///</summary>
    public MyTelegram.Schema.IMessageMedia? Media { get; set; }

    ///<summary>
    /// Reply markup (bot/inline keyboards)
    /// See <a href="https://corefork.telegram.org/type/ReplyMarkup" />
    ///</summary>
    public MyTelegram.Schema.IReplyMarkup? ReplyMarkup { get; set; }

    ///<summary>
    /// Message <a href="https://corefork.telegram.org/api/entities">entities</a> for styled text
    ///</summary>
    public TVector<MyTelegram.Schema.IMessageEntity>? Entities { get; set; }

    ///<summary>
    /// View count for channel posts
    ///</summary>
    public int? Views { get; set; }

    ///<summary>
    /// Forward counter
    ///</summary>
    public int? Forwards { get; set; }

    ///<summary>
    /// Info about <a href="https://corefork.telegram.org/api/threads">post comments (for channels) or message replies (for groups)</a>
    /// See <a href="https://corefork.telegram.org/type/MessageReplies" />
    ///</summary>
    public MyTelegram.Schema.IMessageReplies? Replies { get; set; }

    ///<summary>
    /// Last edit date of this message
    ///</summary>
    public int? EditDate { get; set; }

    ///<summary>
    /// Name of the author of this message for channel posts (with signatures enabled)
    ///</summary>
    public string? PostAuthor { get; set; }

    ///<summary>
    /// Multiple media messages sent using <a href="https://corefork.telegram.org/method/messages.sendMultiMedia">messages.sendMultiMedia</a> with the same grouped ID indicate an <a href="https://corefork.telegram.org/api/files#albums-grouped-media">album or media group</a>
    ///</summary>
    public long? GroupedId { get; set; }

    ///<summary>
    /// Reactions to this message
    /// See <a href="https://corefork.telegram.org/type/MessageReactions" />
    ///</summary>
    public MyTelegram.Schema.IMessageReactions? Reactions { get; set; }

    ///<summary>
    /// Contains the reason why access to this message must be restricted.
    ///</summary>
    public TVector<MyTelegram.Schema.IRestrictionReason>? RestrictionReason { get; set; }

    ///<summary>
    /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well.
    ///</summary>
    public int? TtlPeriod { get; set; }

    ///<summary>
    /// If set, this message is a <a href="https://corefork.telegram.org/api/business#quick-reply-shortcuts">quick reply shortcut message »</a> (note that quick reply shortcut messages <em>sent</em> to a private chat will <em>not</em> have this field set).
    ///</summary>
    public int? QuickReplyShortcutId { get; set; }

    ///<summary>
    /// A <a href="https://corefork.telegram.org/api/effects">message effect that should be played as specified here »</a>.
    ///</summary>
    public long? Effect { get; set; }

    ///<summary>
    /// Represents a <a href="https://corefork.telegram.org/api/factcheck">fact-check »</a>.
    /// See <a href="https://corefork.telegram.org/type/FactCheck" />
    ///</summary>
    public MyTelegram.Schema.IFactCheck? Factcheck { get; set; }
    public int? ReportDeliveryUntilDate { get; set; }
    public long? PaidMessageStars { get; set; }
    public MyTelegram.Schema.ISuggestedPost? SuggestedPost { get; set; }

    public void ComputeFlag()
    {
        if (Out) { Flags = Flags.SetBit(1); }
        if (Mentioned) { Flags = Flags.SetBit(4); }
        if (MediaUnread) { Flags = Flags.SetBit(5); }
        if (Silent) { Flags = Flags.SetBit(13); }
        if (Post) { Flags = Flags.SetBit(14); }
        if (FromScheduled) { Flags = Flags.SetBit(18); }
        if (Legacy) { Flags = Flags.SetBit(19); }
        if (EditHide) { Flags = Flags.SetBit(21); }
        if (Pinned) { Flags = Flags.SetBit(24); }
        if (Noforwards) { Flags = Flags.SetBit(26); }
        if (InvertMedia) { Flags = Flags.SetBit(27); }
        if (Offline) { Flags2 = Flags2.SetBit(1); }
        if (VideoProcessingPending) { Flags2 = Flags2.SetBit(4); }
        if (PaidSuggestedPostStars) { Flags2 = Flags2.SetBit(8); }
        if (PaidSuggestedPostTon) { Flags2 = Flags2.SetBit(9); }
        if (FromId != null) { Flags = Flags.SetBit(8); }
        if (/*FromBoostsApplied != 0 && */FromBoostsApplied.HasValue) { Flags = Flags.SetBit(29); }
        if (SavedPeerId != null) { Flags = Flags.SetBit(28); }
        if (FwdFrom != null) { Flags = Flags.SetBit(2); }
        if (/*ViaBotId != 0 &&*/ ViaBotId.HasValue) { Flags = Flags.SetBit(11); }
        if (/*ViaBusinessBotId != 0 &&*/ ViaBusinessBotId.HasValue) { Flags2 = Flags2.SetBit(0); }
        if (ReplyTo != null) { Flags = Flags.SetBit(3); }
        if (Media != null) { Flags = Flags.SetBit(9); }
        if (ReplyMarkup != null) { Flags = Flags.SetBit(6); }
        if (Entities?.Count > 0) { Flags = Flags.SetBit(7); }
        if (/*Views != 0 && */Views.HasValue) { Flags = Flags.SetBit(10); }
        if (/*Forwards != 0 && */Forwards.HasValue) { Flags = Flags.SetBit(10); }
        if (Replies != null) { Flags = Flags.SetBit(23); }
        if (/*EditDate != 0 && */EditDate.HasValue) { Flags = Flags.SetBit(15); }
        if (PostAuthor != null) { Flags = Flags.SetBit(16); }
        if (/*GroupedId != 0 &&*/ GroupedId.HasValue) { Flags = Flags.SetBit(17); }
        if (Reactions != null) { Flags = Flags.SetBit(20); }
        if (RestrictionReason?.Count > 0) { Flags = Flags.SetBit(22); }
        if (/*TtlPeriod != 0 && */TtlPeriod.HasValue) { Flags = Flags.SetBit(25); }
        if (/*QuickReplyShortcutId != 0 && */QuickReplyShortcutId.HasValue) { Flags = Flags.SetBit(30); }
        if (/*Effect != 0 &&*/ Effect.HasValue) { Flags2 = Flags2.SetBit(2); }
        if (Factcheck != null) { Flags2 = Flags2.SetBit(3); }
        if (/*ReportDeliveryUntilDate != 0 && */ReportDeliveryUntilDate.HasValue) { Flags2 = Flags2.SetBit(5); }
        if (/*PaidMessageStars != 0 &&*/ PaidMessageStars.HasValue) { Flags2 = Flags2.SetBit(6); }
        if (SuggestedPost != null) { Flags2 = Flags2.SetBit(7); }
    }

    public void Serialize(IBufferWriter<byte> writer)
    {
        ComputeFlag();
        writer.Write(ConstructorId);
        writer.Write(Flags);
        writer.Write(Flags2);
        writer.Write(Id);
        if (Flags.IsBitSet(8)) { writer.Write(FromId); }
        if (Flags.IsBitSet(29)) { writer.Write(FromBoostsApplied.Value); }
        writer.Write(PeerId);
        if (Flags.IsBitSet(28)) { writer.Write(SavedPeerId); }
        if (Flags.IsBitSet(2)) { writer.Write(FwdFrom); }
        if (Flags.IsBitSet(11)) { writer.Write(ViaBotId.Value); }
        if (Flags2.IsBitSet(0)) { writer.Write(ViaBusinessBotId.Value); }
        if (Flags.IsBitSet(3)) { writer.Write(ReplyTo); }
        writer.Write(Date);
        writer.Write(Message);
        if (Flags.IsBitSet(9)) { writer.Write(Media); }
        if (Flags.IsBitSet(6)) { writer.Write(ReplyMarkup); }
        if (Flags.IsBitSet(7)) { writer.Write(Entities); }
        if (Flags.IsBitSet(10)) { writer.Write(Views.Value); }
        if (Flags.IsBitSet(10)) { writer.Write(Forwards.Value); }
        if (Flags.IsBitSet(23)) { writer.Write(Replies); }
        if (Flags.IsBitSet(15)) { writer.Write(EditDate.Value); }
        if (Flags.IsBitSet(16)) { writer.Write(PostAuthor); }
        if (Flags.IsBitSet(17)) { writer.Write(GroupedId.Value); }
        if (Flags.IsBitSet(20)) { writer.Write(Reactions); }
        if (Flags.IsBitSet(22)) { writer.Write(RestrictionReason); }
        if (Flags.IsBitSet(25)) { writer.Write(TtlPeriod.Value); }
        if (Flags.IsBitSet(30)) { writer.Write(QuickReplyShortcutId.Value); }
        if (Flags2.IsBitSet(2)) { writer.Write(Effect.Value); }
        if (Flags2.IsBitSet(3)) { writer.Write(Factcheck); }
        if (Flags2.IsBitSet(5)) { writer.Write(ReportDeliveryUntilDate.Value); }
        if (Flags2.IsBitSet(6)) { writer.Write(PaidMessageStars.Value); }
        if (Flags2.IsBitSet(7)) { writer.Write(SuggestedPost); }
    }

    public void Deserialize(ref ReadOnlyMemory<byte> buffer)
    {
        Flags = buffer.ReadInt32();
        if (Flags.IsBitSet(1)) { Out = true; }
        if (Flags.IsBitSet(4)) { Mentioned = true; }
        if (Flags.IsBitSet(5)) { MediaUnread = true; }
        if (Flags.IsBitSet(13)) { Silent = true; }
        if (Flags.IsBitSet(14)) { Post = true; }
        if (Flags.IsBitSet(18)) { FromScheduled = true; }
        if (Flags.IsBitSet(19)) { Legacy = true; }
        if (Flags.IsBitSet(21)) { EditHide = true; }
        if (Flags.IsBitSet(24)) { Pinned = true; }
        if (Flags.IsBitSet(26)) { Noforwards = true; }
        if (Flags.IsBitSet(27)) { InvertMedia = true; }
        Flags2 = buffer.ReadInt32();
        if (Flags2.IsBitSet(1)) { Offline = true; }
        if (Flags2.IsBitSet(4)) { VideoProcessingPending = true; }
        if (Flags2.IsBitSet(8)) { PaidSuggestedPostStars = true; }
        if (Flags2.IsBitSet(9)) { PaidSuggestedPostTon = true; }
        Id = buffer.ReadInt32();
        if (Flags.IsBitSet(8)) { FromId = buffer.Read<MyTelegram.Schema.IPeer>(); }
        if (Flags.IsBitSet(29)) { FromBoostsApplied = buffer.ReadInt32(); }
        PeerId = buffer.Read<MyTelegram.Schema.IPeer>();
        if (Flags.IsBitSet(28)) { SavedPeerId = buffer.Read<MyTelegram.Schema.IPeer>(); }
        if (Flags.IsBitSet(2)) { FwdFrom = buffer.Read<MyTelegram.Schema.IMessageFwdHeader>(); }
        if (Flags.IsBitSet(11)) { ViaBotId = buffer.ReadInt64(); }
        if (Flags2.IsBitSet(0)) { ViaBusinessBotId = buffer.ReadInt64(); }
        if (Flags.IsBitSet(3)) { ReplyTo = buffer.Read<MyTelegram.Schema.IMessageReplyHeader>(); }
        Date = buffer.ReadInt32();
        Message = buffer.ReadString();
        if (Flags.IsBitSet(9)) { Media = buffer.Read<MyTelegram.Schema.IMessageMedia>(); }
        if (Flags.IsBitSet(6)) { ReplyMarkup = buffer.Read<MyTelegram.Schema.IReplyMarkup>(); }
        if (Flags.IsBitSet(7)) { Entities = buffer.Read<TVector<MyTelegram.Schema.IMessageEntity>>(); }
        if (Flags.IsBitSet(10)) { Views = buffer.ReadInt32(); }
        if (Flags.IsBitSet(10)) { Forwards = buffer.ReadInt32(); }
        if (Flags.IsBitSet(23)) { Replies = buffer.Read<MyTelegram.Schema.IMessageReplies>(); }
        if (Flags.IsBitSet(15)) { EditDate = buffer.ReadInt32(); }
        if (Flags.IsBitSet(16)) { PostAuthor = buffer.ReadString(); }
        if (Flags.IsBitSet(17)) { GroupedId = buffer.ReadInt64(); }
        if (Flags.IsBitSet(20)) { Reactions = buffer.Read<MyTelegram.Schema.IMessageReactions>(); }
        if (Flags.IsBitSet(22)) { RestrictionReason = buffer.Read<TVector<MyTelegram.Schema.IRestrictionReason>>(); }
        if (Flags.IsBitSet(25)) { TtlPeriod = buffer.ReadInt32(); }
        if (Flags.IsBitSet(30)) { QuickReplyShortcutId = buffer.ReadInt32(); }
        if (Flags2.IsBitSet(2)) { Effect = buffer.ReadInt64(); }
        if (Flags2.IsBitSet(3)) { Factcheck = buffer.Read<MyTelegram.Schema.IFactCheck>(); }
        if (Flags2.IsBitSet(5)) { ReportDeliveryUntilDate = buffer.ReadInt32(); }
        if (Flags2.IsBitSet(6)) { PaidMessageStars = buffer.ReadInt64(); }
        if (Flags2.IsBitSet(7)) { SuggestedPost = buffer.Read<MyTelegram.Schema.ISuggestedPost>(); }
    }
}