// Code generated by gotdgen, DO NOT EDIT.

package tg

import (
	"context"
	"errors"
	"fmt"
	"sort"
	"strings"

	"go.uber.org/multierr"

	"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tdjson"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tdp"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tgerr"
)

// No-op definition for keeping imports.
var (
	_ = bin.Buffer{}
	_ = context.Background()
	_ = fmt.Stringer(nil)
	_ = strings.Builder{}
	_ = errors.Is
	_ = multierr.AppendInto
	_ = sort.Ints
	_ = tdp.Format
	_ = tgerr.Error{}
	_ = tdjson.Encoder{}
)

// PaymentsGetSavedStarGiftsRequest represents TL type `payments.getSavedStarGifts#a319e569`.
// Fetch the full list of gifts¹ owned by a peer.
// Note that unlike what the name suggests, the method can be used to fetch both "saved"
// and "unsaved" gifts (aka gifts both pinned and not pinned) to the profile, depending
// on the passed flags.
//
// Links:
//  1. https://core.telegram.org/api/gifts
//
// See https://core.telegram.org/method/payments.getSavedStarGifts for reference.
type PaymentsGetSavedStarGiftsRequest struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Exclude gifts not pinned on the profile.
	ExcludeUnsaved bool
	// Exclude gifts pinned on the profile.
	ExcludeSaved bool
	// Exclude gifts that do not have the starGift¹.limited flag set.
	//
	// Links:
	//  1) https://core.telegram.org/constructor/starGift
	ExcludeUnlimited bool
	// Exclude collectible gifts »¹.
	//
	// Links:
	//  1) https://core.telegram.org/api/gifts#collectible-gifts
	ExcludeUnique bool
	// If set, sorts the gifts by price instead of reception date.
	SortByValue bool
	// Exclude gifts that can be upgraded to collectible gifts »¹.
	//
	// Links:
	//  1) https://core.telegram.org/api/gifts#collectible-gifts
	ExcludeUpgradable bool
	// Exclude gifts that cannot be upgraded to collectible gifts »¹.
	//
	// Links:
	//  1) https://core.telegram.org/api/gifts#collectible-gifts
	ExcludeUnupgradable bool
	// PeerColorAvailable field of PaymentsGetSavedStarGiftsRequest.
	PeerColorAvailable bool
	// ExcludeHosted field of PaymentsGetSavedStarGiftsRequest.
	ExcludeHosted bool
	// Fetch only gifts owned by the specified peer, such as: a user, with
	// peer=inputPeerUser¹; a channel, with peer=inputPeerChannel²; a connected business
	// user³ (when executing the method as a bot, over the business connection), with
	// peer=inputPeerUser⁴.
	//
	// Links:
	//  1) https://core.telegram.org/constructor/inputPeerUser
	//  2) https://core.telegram.org/constructor/inputPeerChannel
	//  3) https://core.telegram.org/api/bots/connected-business-bots
	//  4) https://core.telegram.org/constructor/inputPeerUser
	Peer InputPeerClass
	// Only returns gifts within the specified collection »¹.
	//
	// Links:
	//  1) https://core.telegram.org/api/gifts#gift-collections
	//
	// Use SetCollectionID and GetCollectionID helpers.
	CollectionID int
	// Offset for pagination¹.
	//
	// Links:
	//  1) https://core.telegram.org/api/offsets
	Offset string
	// Maximum number of results to return, see pagination¹
	//
	// Links:
	//  1) https://core.telegram.org/api/offsets
	Limit int
}

// PaymentsGetSavedStarGiftsRequestTypeID is TL type id of PaymentsGetSavedStarGiftsRequest.
const PaymentsGetSavedStarGiftsRequestTypeID = 0xa319e569

// Ensuring interfaces in compile-time for PaymentsGetSavedStarGiftsRequest.
var (
	_ bin.Encoder     = &PaymentsGetSavedStarGiftsRequest{}
	_ bin.Decoder     = &PaymentsGetSavedStarGiftsRequest{}
	_ bin.BareEncoder = &PaymentsGetSavedStarGiftsRequest{}
	_ bin.BareDecoder = &PaymentsGetSavedStarGiftsRequest{}
)

func (g *PaymentsGetSavedStarGiftsRequest) Zero() bool {
	if g == nil {
		return true
	}
	if !(g.Flags.Zero()) {
		return false
	}
	if !(g.ExcludeUnsaved == false) {
		return false
	}
	if !(g.ExcludeSaved == false) {
		return false
	}
	if !(g.ExcludeUnlimited == false) {
		return false
	}
	if !(g.ExcludeUnique == false) {
		return false
	}
	if !(g.SortByValue == false) {
		return false
	}
	if !(g.ExcludeUpgradable == false) {
		return false
	}
	if !(g.ExcludeUnupgradable == false) {
		return false
	}
	if !(g.PeerColorAvailable == false) {
		return false
	}
	if !(g.ExcludeHosted == false) {
		return false
	}
	if !(g.Peer == nil) {
		return false
	}
	if !(g.CollectionID == 0) {
		return false
	}
	if !(g.Offset == "") {
		return false
	}
	if !(g.Limit == 0) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (g *PaymentsGetSavedStarGiftsRequest) String() string {
	if g == nil {
		return "PaymentsGetSavedStarGiftsRequest(nil)"
	}
	type Alias PaymentsGetSavedStarGiftsRequest
	return fmt.Sprintf("PaymentsGetSavedStarGiftsRequest%+v", Alias(*g))
}

// FillFrom fills PaymentsGetSavedStarGiftsRequest from given interface.
func (g *PaymentsGetSavedStarGiftsRequest) FillFrom(from interface {
	GetExcludeUnsaved() (value bool)
	GetExcludeSaved() (value bool)
	GetExcludeUnlimited() (value bool)
	GetExcludeUnique() (value bool)
	GetSortByValue() (value bool)
	GetExcludeUpgradable() (value bool)
	GetExcludeUnupgradable() (value bool)
	GetPeerColorAvailable() (value bool)
	GetExcludeHosted() (value bool)
	GetPeer() (value InputPeerClass)
	GetCollectionID() (value int, ok bool)
	GetOffset() (value string)
	GetLimit() (value int)
}) {
	g.ExcludeUnsaved = from.GetExcludeUnsaved()
	g.ExcludeSaved = from.GetExcludeSaved()
	g.ExcludeUnlimited = from.GetExcludeUnlimited()
	g.ExcludeUnique = from.GetExcludeUnique()
	g.SortByValue = from.GetSortByValue()
	g.ExcludeUpgradable = from.GetExcludeUpgradable()
	g.ExcludeUnupgradable = from.GetExcludeUnupgradable()
	g.PeerColorAvailable = from.GetPeerColorAvailable()
	g.ExcludeHosted = from.GetExcludeHosted()
	g.Peer = from.GetPeer()
	if val, ok := from.GetCollectionID(); ok {
		g.CollectionID = val
	}

	g.Offset = from.GetOffset()
	g.Limit = from.GetLimit()
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*PaymentsGetSavedStarGiftsRequest) TypeID() uint32 {
	return PaymentsGetSavedStarGiftsRequestTypeID
}

// TypeName returns name of type in TL schema.
func (*PaymentsGetSavedStarGiftsRequest) TypeName() string {
	return "payments.getSavedStarGifts"
}

// TypeInfo returns info about TL type.
func (g *PaymentsGetSavedStarGiftsRequest) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "payments.getSavedStarGifts",
		ID:   PaymentsGetSavedStarGiftsRequestTypeID,
	}
	if g == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "ExcludeUnsaved",
			SchemaName: "exclude_unsaved",
			Null:       !g.Flags.Has(0),
		},
		{
			Name:       "ExcludeSaved",
			SchemaName: "exclude_saved",
			Null:       !g.Flags.Has(1),
		},
		{
			Name:       "ExcludeUnlimited",
			SchemaName: "exclude_unlimited",
			Null:       !g.Flags.Has(2),
		},
		{
			Name:       "ExcludeUnique",
			SchemaName: "exclude_unique",
			Null:       !g.Flags.Has(4),
		},
		{
			Name:       "SortByValue",
			SchemaName: "sort_by_value",
			Null:       !g.Flags.Has(5),
		},
		{
			Name:       "ExcludeUpgradable",
			SchemaName: "exclude_upgradable",
			Null:       !g.Flags.Has(7),
		},
		{
			Name:       "ExcludeUnupgradable",
			SchemaName: "exclude_unupgradable",
			Null:       !g.Flags.Has(8),
		},
		{
			Name:       "PeerColorAvailable",
			SchemaName: "peer_color_available",
			Null:       !g.Flags.Has(9),
		},
		{
			Name:       "ExcludeHosted",
			SchemaName: "exclude_hosted",
			Null:       !g.Flags.Has(10),
		},
		{
			Name:       "Peer",
			SchemaName: "peer",
		},
		{
			Name:       "CollectionID",
			SchemaName: "collection_id",
			Null:       !g.Flags.Has(6),
		},
		{
			Name:       "Offset",
			SchemaName: "offset",
		},
		{
			Name:       "Limit",
			SchemaName: "limit",
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (g *PaymentsGetSavedStarGiftsRequest) SetFlags() {
	if !(g.ExcludeUnsaved == false) {
		g.Flags.Set(0)
	}
	if !(g.ExcludeSaved == false) {
		g.Flags.Set(1)
	}
	if !(g.ExcludeUnlimited == false) {
		g.Flags.Set(2)
	}
	if !(g.ExcludeUnique == false) {
		g.Flags.Set(4)
	}
	if !(g.SortByValue == false) {
		g.Flags.Set(5)
	}
	if !(g.ExcludeUpgradable == false) {
		g.Flags.Set(7)
	}
	if !(g.ExcludeUnupgradable == false) {
		g.Flags.Set(8)
	}
	if !(g.PeerColorAvailable == false) {
		g.Flags.Set(9)
	}
	if !(g.ExcludeHosted == false) {
		g.Flags.Set(10)
	}
	if !(g.CollectionID == 0) {
		g.Flags.Set(6)
	}
}

// Encode implements bin.Encoder.
func (g *PaymentsGetSavedStarGiftsRequest) Encode(b *bin.Buffer) error {
	if g == nil {
		return fmt.Errorf("can't encode payments.getSavedStarGifts#a319e569 as nil")
	}
	b.PutID(PaymentsGetSavedStarGiftsRequestTypeID)
	return g.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (g *PaymentsGetSavedStarGiftsRequest) EncodeBare(b *bin.Buffer) error {
	if g == nil {
		return fmt.Errorf("can't encode payments.getSavedStarGifts#a319e569 as nil")
	}
	g.SetFlags()
	if err := g.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode payments.getSavedStarGifts#a319e569: field flags: %w", err)
	}
	if g.Peer == nil {
		return fmt.Errorf("unable to encode payments.getSavedStarGifts#a319e569: field peer is nil")
	}
	if err := g.Peer.Encode(b); err != nil {
		return fmt.Errorf("unable to encode payments.getSavedStarGifts#a319e569: field peer: %w", err)
	}
	if g.Flags.Has(6) {
		b.PutInt(g.CollectionID)
	}
	b.PutString(g.Offset)
	b.PutInt(g.Limit)
	return nil
}

// Decode implements bin.Decoder.
func (g *PaymentsGetSavedStarGiftsRequest) Decode(b *bin.Buffer) error {
	if g == nil {
		return fmt.Errorf("can't decode payments.getSavedStarGifts#a319e569 to nil")
	}
	if err := b.ConsumeID(PaymentsGetSavedStarGiftsRequestTypeID); err != nil {
		return fmt.Errorf("unable to decode payments.getSavedStarGifts#a319e569: %w", err)
	}
	return g.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (g *PaymentsGetSavedStarGiftsRequest) DecodeBare(b *bin.Buffer) error {
	if g == nil {
		return fmt.Errorf("can't decode payments.getSavedStarGifts#a319e569 to nil")
	}
	{
		if err := g.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode payments.getSavedStarGifts#a319e569: field flags: %w", err)
		}
	}
	g.ExcludeUnsaved = g.Flags.Has(0)
	g.ExcludeSaved = g.Flags.Has(1)
	g.ExcludeUnlimited = g.Flags.Has(2)
	g.ExcludeUnique = g.Flags.Has(4)
	g.SortByValue = g.Flags.Has(5)
	g.ExcludeUpgradable = g.Flags.Has(7)
	g.ExcludeUnupgradable = g.Flags.Has(8)
	g.PeerColorAvailable = g.Flags.Has(9)
	g.ExcludeHosted = g.Flags.Has(10)
	{
		value, err := DecodeInputPeer(b)
		if err != nil {
			return fmt.Errorf("unable to decode payments.getSavedStarGifts#a319e569: field peer: %w", err)
		}
		g.Peer = value
	}
	if g.Flags.Has(6) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode payments.getSavedStarGifts#a319e569: field collection_id: %w", err)
		}
		g.CollectionID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode payments.getSavedStarGifts#a319e569: field offset: %w", err)
		}
		g.Offset = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode payments.getSavedStarGifts#a319e569: field limit: %w", err)
		}
		g.Limit = value
	}
	return nil
}

// SetExcludeUnsaved sets value of ExcludeUnsaved conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeUnsaved(value bool) {
	if value {
		g.Flags.Set(0)
		g.ExcludeUnsaved = true
	} else {
		g.Flags.Unset(0)
		g.ExcludeUnsaved = false
	}
}

// GetExcludeUnsaved returns value of ExcludeUnsaved conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeUnsaved() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(0)
}

// SetExcludeSaved sets value of ExcludeSaved conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeSaved(value bool) {
	if value {
		g.Flags.Set(1)
		g.ExcludeSaved = true
	} else {
		g.Flags.Unset(1)
		g.ExcludeSaved = false
	}
}

// GetExcludeSaved returns value of ExcludeSaved conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeSaved() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(1)
}

// SetExcludeUnlimited sets value of ExcludeUnlimited conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeUnlimited(value bool) {
	if value {
		g.Flags.Set(2)
		g.ExcludeUnlimited = true
	} else {
		g.Flags.Unset(2)
		g.ExcludeUnlimited = false
	}
}

// GetExcludeUnlimited returns value of ExcludeUnlimited conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeUnlimited() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(2)
}

// SetExcludeUnique sets value of ExcludeUnique conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeUnique(value bool) {
	if value {
		g.Flags.Set(4)
		g.ExcludeUnique = true
	} else {
		g.Flags.Unset(4)
		g.ExcludeUnique = false
	}
}

// GetExcludeUnique returns value of ExcludeUnique conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeUnique() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(4)
}

// SetSortByValue sets value of SortByValue conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetSortByValue(value bool) {
	if value {
		g.Flags.Set(5)
		g.SortByValue = true
	} else {
		g.Flags.Unset(5)
		g.SortByValue = false
	}
}

// GetSortByValue returns value of SortByValue conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetSortByValue() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(5)
}

// SetExcludeUpgradable sets value of ExcludeUpgradable conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeUpgradable(value bool) {
	if value {
		g.Flags.Set(7)
		g.ExcludeUpgradable = true
	} else {
		g.Flags.Unset(7)
		g.ExcludeUpgradable = false
	}
}

// GetExcludeUpgradable returns value of ExcludeUpgradable conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeUpgradable() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(7)
}

// SetExcludeUnupgradable sets value of ExcludeUnupgradable conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeUnupgradable(value bool) {
	if value {
		g.Flags.Set(8)
		g.ExcludeUnupgradable = true
	} else {
		g.Flags.Unset(8)
		g.ExcludeUnupgradable = false
	}
}

// GetExcludeUnupgradable returns value of ExcludeUnupgradable conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeUnupgradable() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(8)
}

// SetPeerColorAvailable sets value of PeerColorAvailable conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetPeerColorAvailable(value bool) {
	if value {
		g.Flags.Set(9)
		g.PeerColorAvailable = true
	} else {
		g.Flags.Unset(9)
		g.PeerColorAvailable = false
	}
}

// GetPeerColorAvailable returns value of PeerColorAvailable conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetPeerColorAvailable() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(9)
}

// SetExcludeHosted sets value of ExcludeHosted conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetExcludeHosted(value bool) {
	if value {
		g.Flags.Set(10)
		g.ExcludeHosted = true
	} else {
		g.Flags.Unset(10)
		g.ExcludeHosted = false
	}
}

// GetExcludeHosted returns value of ExcludeHosted conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) GetExcludeHosted() (value bool) {
	if g == nil {
		return
	}
	return g.Flags.Has(10)
}

// GetPeer returns value of Peer field.
func (g *PaymentsGetSavedStarGiftsRequest) GetPeer() (value InputPeerClass) {
	if g == nil {
		return
	}
	return g.Peer
}

// SetCollectionID sets value of CollectionID conditional field.
func (g *PaymentsGetSavedStarGiftsRequest) SetCollectionID(value int) {
	g.Flags.Set(6)
	g.CollectionID = value
}

// GetCollectionID returns value of CollectionID conditional field and
// boolean which is true if field was set.
func (g *PaymentsGetSavedStarGiftsRequest) GetCollectionID() (value int, ok bool) {
	if g == nil {
		return
	}
	if !g.Flags.Has(6) {
		return value, false
	}
	return g.CollectionID, true
}

// GetOffset returns value of Offset field.
func (g *PaymentsGetSavedStarGiftsRequest) GetOffset() (value string) {
	if g == nil {
		return
	}
	return g.Offset
}

// GetLimit returns value of Limit field.
func (g *PaymentsGetSavedStarGiftsRequest) GetLimit() (value int) {
	if g == nil {
		return
	}
	return g.Limit
}

// PaymentsGetSavedStarGifts invokes method payments.getSavedStarGifts#a319e569 returning error if any.
// Fetch the full list of gifts¹ owned by a peer.
// Note that unlike what the name suggests, the method can be used to fetch both "saved"
// and "unsaved" gifts (aka gifts both pinned and not pinned) to the profile, depending
// on the passed flags.
//
// Links:
//  1. https://core.telegram.org/api/gifts
//
// Possible errors:
//
//	400 BUSINESS_CONNECTION_INVALID: The connection_id passed to the wrapping invokeWithBusinessConnection call is invalid.
//	400 PEER_ID_INVALID: The provided peer id is invalid.
//
// See https://core.telegram.org/method/payments.getSavedStarGifts for reference.
func (c *Client) PaymentsGetSavedStarGifts(ctx context.Context, request *PaymentsGetSavedStarGiftsRequest) (*PaymentsSavedStarGifts, error) {
	var result PaymentsSavedStarGifts

	if err := c.rpc.Invoke(ctx, request, &result); err != nil {
		return nil, err
	}
	return &result, nil
}
