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

namespace MyTelegram.Schema;

///<summary>
/// Info about a group call or livestream
/// See <a href="https://corefork.telegram.org/constructor/groupCall" />
///</summary>
[TlObject(0x553b0ba1)]
public sealed class TGroupCall : IGroupCall
{
    public uint ConstructorId => 0x553b0ba1;
    ///<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>
    /// Whether the user should be muted upon joining the call
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool JoinMuted { get; set; }

    ///<summary>
    /// Whether the current user can change the value of the <code>join_muted</code> flag using <a href="https://corefork.telegram.org/method/phone.toggleGroupCallSettings">phone.toggleGroupCallSettings</a>
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool CanChangeJoinMuted { get; set; }

    ///<summary>
    /// Specifies the ordering to use when locally sorting by date and displaying in the UI group call participants.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool JoinDateAsc { get; set; }

    ///<summary>
    /// Whether we subscribed to the scheduled call
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool ScheduleStartSubscribed { get; set; }

    ///<summary>
    /// Whether you can start streaming video into the call
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool CanStartVideo { get; set; }

    ///<summary>
    /// Whether the group call is currently being recorded
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool RecordVideoActive { get; set; }

    ///<summary>
    /// Whether RTMP streams are allowed
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool RtmpStream { get; set; }

    ///<summary>
    /// Whether the listeners list is hidden and cannot be fetched using <a href="https://corefork.telegram.org/method/phone.getGroupParticipants">phone.getGroupParticipants</a>. The <code>phone.groupParticipants.count</code> and <code>groupCall.participants_count</code> counters will still include listeners.
    /// See <a href="https://corefork.telegram.org/type/true" />
    ///</summary>
    public bool ListenersHidden { get; set; }
    public bool Conference { get; set; }
    public bool Creator { get; set; }

    ///<summary>
    /// Group call ID
    ///</summary>
    public long Id { get; set; }

    ///<summary>
    /// Group call access hash
    ///</summary>
    public long AccessHash { get; set; }

    ///<summary>
    /// Participant count
    ///</summary>
    public int ParticipantsCount { get; set; }

    ///<summary>
    /// Group call title
    ///</summary>
    public string? Title { get; set; }

    ///<summary>
    /// DC ID to be used for livestream chunks
    ///</summary>
    public int? StreamDcId { get; set; }

    ///<summary>
    /// When was the recording started
    ///</summary>
    public int? RecordStartDate { get; set; }

    ///<summary>
    /// When is the call scheduled to start
    ///</summary>
    public int? ScheduleDate { get; set; }

    ///<summary>
    /// Number of people currently streaming video into the call
    ///</summary>
    public int? UnmutedVideoCount { get; set; }

    ///<summary>
    /// Maximum number of people allowed to stream video into the call
    ///</summary>
    public int UnmutedVideoLimit { get; set; }

    ///<summary>
    /// Version
    ///</summary>
    public int Version { get; set; }
    public string? InviteLink { get; set; }

    public void ComputeFlag()
    {
        if (JoinMuted) { Flags = Flags.SetBit(1); }
        if (CanChangeJoinMuted) { Flags = Flags.SetBit(2); }
        if (JoinDateAsc) { Flags = Flags.SetBit(6); }
        if (ScheduleStartSubscribed) { Flags = Flags.SetBit(8); }
        if (CanStartVideo) { Flags = Flags.SetBit(9); }
        if (RecordVideoActive) { Flags = Flags.SetBit(11); }
        if (RtmpStream) { Flags = Flags.SetBit(12); }
        if (ListenersHidden) { Flags = Flags.SetBit(13); }
        if (Conference) { Flags = Flags.SetBit(14); }
        if (Creator) { Flags = Flags.SetBit(15); }
        if (Title != null) { Flags = Flags.SetBit(3); }
        if (/*StreamDcId != 0 && */StreamDcId.HasValue) { Flags = Flags.SetBit(4); }
        if (/*RecordStartDate != 0 && */RecordStartDate.HasValue) { Flags = Flags.SetBit(5); }
        if (/*ScheduleDate != 0 && */ScheduleDate.HasValue) { Flags = Flags.SetBit(7); }
        if (/*UnmutedVideoCount != 0 && */UnmutedVideoCount.HasValue) { Flags = Flags.SetBit(10); }
        if (InviteLink != null) { Flags = Flags.SetBit(16); }
    }

    public void Serialize(IBufferWriter<byte> writer)
    {
        ComputeFlag();
        writer.Write(ConstructorId);
        writer.Write(Flags);
        writer.Write(Id);
        writer.Write(AccessHash);
        writer.Write(ParticipantsCount);
        if (Flags.IsBitSet(3)) { writer.Write(Title); }
        if (Flags.IsBitSet(4)) { writer.Write(StreamDcId.Value); }
        if (Flags.IsBitSet(5)) { writer.Write(RecordStartDate.Value); }
        if (Flags.IsBitSet(7)) { writer.Write(ScheduleDate.Value); }
        if (Flags.IsBitSet(10)) { writer.Write(UnmutedVideoCount.Value); }
        writer.Write(UnmutedVideoLimit);
        writer.Write(Version);
        if (Flags.IsBitSet(16)) { writer.Write(InviteLink); }
    }

    public void Deserialize(ref ReadOnlyMemory<byte> buffer)
    {
        Flags = buffer.ReadInt32();
        if (Flags.IsBitSet(1)) { JoinMuted = true; }
        if (Flags.IsBitSet(2)) { CanChangeJoinMuted = true; }
        if (Flags.IsBitSet(6)) { JoinDateAsc = true; }
        if (Flags.IsBitSet(8)) { ScheduleStartSubscribed = true; }
        if (Flags.IsBitSet(9)) { CanStartVideo = true; }
        if (Flags.IsBitSet(11)) { RecordVideoActive = true; }
        if (Flags.IsBitSet(12)) { RtmpStream = true; }
        if (Flags.IsBitSet(13)) { ListenersHidden = true; }
        if (Flags.IsBitSet(14)) { Conference = true; }
        if (Flags.IsBitSet(15)) { Creator = true; }
        Id = buffer.ReadInt64();
        AccessHash = buffer.ReadInt64();
        ParticipantsCount = buffer.ReadInt32();
        if (Flags.IsBitSet(3)) { Title = buffer.ReadString(); }
        if (Flags.IsBitSet(4)) { StreamDcId = buffer.ReadInt32(); }
        if (Flags.IsBitSet(5)) { RecordStartDate = buffer.ReadInt32(); }
        if (Flags.IsBitSet(7)) { ScheduleDate = buffer.ReadInt32(); }
        if (Flags.IsBitSet(10)) { UnmutedVideoCount = buffer.ReadInt32(); }
        UnmutedVideoLimit = buffer.ReadInt32();
        Version = buffer.ReadInt32();
        if (Flags.IsBitSet(16)) { InviteLink = buffer.ReadString(); }
    }
}