// 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{}
)

// PaymentsUniqueStarGiftValueInfo represents TL type `payments.uniqueStarGiftValueInfo#512fe446`.
// Information about the value of a collectible gift »¹.
//
// Links:
//  1. https://core.telegram.org/api/gifts#collectible-gifts
//
// See https://core.telegram.org/constructor/payments.uniqueStarGiftValueInfo for reference.
type PaymentsUniqueStarGiftValueInfo struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// If set, the last sale was completed on Fragment.
	LastSaleOnFragment bool
	// If set, the value is calculated from the average value of sold gifts of the same type.
	// Otherwise, it is based on the sale price of the gift.
	ValueIsAverage bool
	// Three-letter ISO 4217 currency¹ code (a localized fiat currency used to represent
	// prices and price estimations in this constructor).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Estimated value of the gift, in the smallest unit of the currency specified in
	// currency.
	Value int64
	// Initial purchase date of the gift.
	InitialSaleDate int
	// Initial purchase price in Stars.
	InitialSaleStars int64
	// Initial purchase price in the smallest unit of the currency specified in currency
	// (automatically converted from initial_sale_stars).
	InitialSalePrice int64
	// Last resale date of the gift.
	//
	// Use SetLastSaleDate and GetLastSaleDate helpers.
	LastSaleDate int
	// Last resale price, in the smallest unit of the currency specified in currency.
	//
	// Use SetLastSalePrice and GetLastSalePrice helpers.
	LastSalePrice int64
	// The current minimum price of collectible gifts of the same type, in the smallest unit
	// of the currency specified in currency.
	//
	// Use SetFloorPrice and GetFloorPrice helpers.
	FloorPrice int64
	// The current average sale price of collectible gifts of the same type, in the smallest
	// unit of the currency specified in currency.
	//
	// Use SetAveragePrice and GetAveragePrice helpers.
	AveragePrice int64
	// Number of gifts of the same type currently being resold on Telegram.
	//
	// Use SetListedCount and GetListedCount helpers.
	ListedCount int
	// Number of gifts of the same type currently being resold on fragment.
	//
	// Use SetFragmentListedCount and GetFragmentListedCount helpers.
	FragmentListedCount int
	// Fragment link to the listing of gifts of the same type currently being resold on
	// fragment.
	//
	// Use SetFragmentListedURL and GetFragmentListedURL helpers.
	FragmentListedURL string
}

// PaymentsUniqueStarGiftValueInfoTypeID is TL type id of PaymentsUniqueStarGiftValueInfo.
const PaymentsUniqueStarGiftValueInfoTypeID = 0x512fe446

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

func (u *PaymentsUniqueStarGiftValueInfo) Zero() bool {
	if u == nil {
		return true
	}
	if !(u.Flags.Zero()) {
		return false
	}
	if !(u.LastSaleOnFragment == false) {
		return false
	}
	if !(u.ValueIsAverage == false) {
		return false
	}
	if !(u.Currency == "") {
		return false
	}
	if !(u.Value == 0) {
		return false
	}
	if !(u.InitialSaleDate == 0) {
		return false
	}
	if !(u.InitialSaleStars == 0) {
		return false
	}
	if !(u.InitialSalePrice == 0) {
		return false
	}
	if !(u.LastSaleDate == 0) {
		return false
	}
	if !(u.LastSalePrice == 0) {
		return false
	}
	if !(u.FloorPrice == 0) {
		return false
	}
	if !(u.AveragePrice == 0) {
		return false
	}
	if !(u.ListedCount == 0) {
		return false
	}
	if !(u.FragmentListedCount == 0) {
		return false
	}
	if !(u.FragmentListedURL == "") {
		return false
	}

	return true
}

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

// FillFrom fills PaymentsUniqueStarGiftValueInfo from given interface.
func (u *PaymentsUniqueStarGiftValueInfo) FillFrom(from interface {
	GetLastSaleOnFragment() (value bool)
	GetValueIsAverage() (value bool)
	GetCurrency() (value string)
	GetValue() (value int64)
	GetInitialSaleDate() (value int)
	GetInitialSaleStars() (value int64)
	GetInitialSalePrice() (value int64)
	GetLastSaleDate() (value int, ok bool)
	GetLastSalePrice() (value int64, ok bool)
	GetFloorPrice() (value int64, ok bool)
	GetAveragePrice() (value int64, ok bool)
	GetListedCount() (value int, ok bool)
	GetFragmentListedCount() (value int, ok bool)
	GetFragmentListedURL() (value string, ok bool)
}) {
	u.LastSaleOnFragment = from.GetLastSaleOnFragment()
	u.ValueIsAverage = from.GetValueIsAverage()
	u.Currency = from.GetCurrency()
	u.Value = from.GetValue()
	u.InitialSaleDate = from.GetInitialSaleDate()
	u.InitialSaleStars = from.GetInitialSaleStars()
	u.InitialSalePrice = from.GetInitialSalePrice()
	if val, ok := from.GetLastSaleDate(); ok {
		u.LastSaleDate = val
	}

	if val, ok := from.GetLastSalePrice(); ok {
		u.LastSalePrice = val
	}

	if val, ok := from.GetFloorPrice(); ok {
		u.FloorPrice = val
	}

	if val, ok := from.GetAveragePrice(); ok {
		u.AveragePrice = val
	}

	if val, ok := from.GetListedCount(); ok {
		u.ListedCount = val
	}

	if val, ok := from.GetFragmentListedCount(); ok {
		u.FragmentListedCount = val
	}

	if val, ok := from.GetFragmentListedURL(); ok {
		u.FragmentListedURL = val
	}

}

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

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

// TypeInfo returns info about TL type.
func (u *PaymentsUniqueStarGiftValueInfo) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "payments.uniqueStarGiftValueInfo",
		ID:   PaymentsUniqueStarGiftValueInfoTypeID,
	}
	if u == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "LastSaleOnFragment",
			SchemaName: "last_sale_on_fragment",
			Null:       !u.Flags.Has(1),
		},
		{
			Name:       "ValueIsAverage",
			SchemaName: "value_is_average",
			Null:       !u.Flags.Has(6),
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Value",
			SchemaName: "value",
		},
		{
			Name:       "InitialSaleDate",
			SchemaName: "initial_sale_date",
		},
		{
			Name:       "InitialSaleStars",
			SchemaName: "initial_sale_stars",
		},
		{
			Name:       "InitialSalePrice",
			SchemaName: "initial_sale_price",
		},
		{
			Name:       "LastSaleDate",
			SchemaName: "last_sale_date",
			Null:       !u.Flags.Has(0),
		},
		{
			Name:       "LastSalePrice",
			SchemaName: "last_sale_price",
			Null:       !u.Flags.Has(0),
		},
		{
			Name:       "FloorPrice",
			SchemaName: "floor_price",
			Null:       !u.Flags.Has(2),
		},
		{
			Name:       "AveragePrice",
			SchemaName: "average_price",
			Null:       !u.Flags.Has(3),
		},
		{
			Name:       "ListedCount",
			SchemaName: "listed_count",
			Null:       !u.Flags.Has(4),
		},
		{
			Name:       "FragmentListedCount",
			SchemaName: "fragment_listed_count",
			Null:       !u.Flags.Has(5),
		},
		{
			Name:       "FragmentListedURL",
			SchemaName: "fragment_listed_url",
			Null:       !u.Flags.Has(5),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (u *PaymentsUniqueStarGiftValueInfo) SetFlags() {
	if !(u.LastSaleOnFragment == false) {
		u.Flags.Set(1)
	}
	if !(u.ValueIsAverage == false) {
		u.Flags.Set(6)
	}
	if !(u.LastSaleDate == 0) {
		u.Flags.Set(0)
	}
	if !(u.LastSalePrice == 0) {
		u.Flags.Set(0)
	}
	if !(u.FloorPrice == 0) {
		u.Flags.Set(2)
	}
	if !(u.AveragePrice == 0) {
		u.Flags.Set(3)
	}
	if !(u.ListedCount == 0) {
		u.Flags.Set(4)
	}
	if !(u.FragmentListedCount == 0) {
		u.Flags.Set(5)
	}
	if !(u.FragmentListedURL == "") {
		u.Flags.Set(5)
	}
}

// Encode implements bin.Encoder.
func (u *PaymentsUniqueStarGiftValueInfo) Encode(b *bin.Buffer) error {
	if u == nil {
		return fmt.Errorf("can't encode payments.uniqueStarGiftValueInfo#512fe446 as nil")
	}
	b.PutID(PaymentsUniqueStarGiftValueInfoTypeID)
	return u.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (u *PaymentsUniqueStarGiftValueInfo) EncodeBare(b *bin.Buffer) error {
	if u == nil {
		return fmt.Errorf("can't encode payments.uniqueStarGiftValueInfo#512fe446 as nil")
	}
	u.SetFlags()
	if err := u.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode payments.uniqueStarGiftValueInfo#512fe446: field flags: %w", err)
	}
	b.PutString(u.Currency)
	b.PutLong(u.Value)
	b.PutInt(u.InitialSaleDate)
	b.PutLong(u.InitialSaleStars)
	b.PutLong(u.InitialSalePrice)
	if u.Flags.Has(0) {
		b.PutInt(u.LastSaleDate)
	}
	if u.Flags.Has(0) {
		b.PutLong(u.LastSalePrice)
	}
	if u.Flags.Has(2) {
		b.PutLong(u.FloorPrice)
	}
	if u.Flags.Has(3) {
		b.PutLong(u.AveragePrice)
	}
	if u.Flags.Has(4) {
		b.PutInt(u.ListedCount)
	}
	if u.Flags.Has(5) {
		b.PutInt(u.FragmentListedCount)
	}
	if u.Flags.Has(5) {
		b.PutString(u.FragmentListedURL)
	}
	return nil
}

// Decode implements bin.Decoder.
func (u *PaymentsUniqueStarGiftValueInfo) Decode(b *bin.Buffer) error {
	if u == nil {
		return fmt.Errorf("can't decode payments.uniqueStarGiftValueInfo#512fe446 to nil")
	}
	if err := b.ConsumeID(PaymentsUniqueStarGiftValueInfoTypeID); err != nil {
		return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: %w", err)
	}
	return u.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (u *PaymentsUniqueStarGiftValueInfo) DecodeBare(b *bin.Buffer) error {
	if u == nil {
		return fmt.Errorf("can't decode payments.uniqueStarGiftValueInfo#512fe446 to nil")
	}
	{
		if err := u.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field flags: %w", err)
		}
	}
	u.LastSaleOnFragment = u.Flags.Has(1)
	u.ValueIsAverage = u.Flags.Has(6)
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field currency: %w", err)
		}
		u.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field value: %w", err)
		}
		u.Value = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field initial_sale_date: %w", err)
		}
		u.InitialSaleDate = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field initial_sale_stars: %w", err)
		}
		u.InitialSaleStars = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field initial_sale_price: %w", err)
		}
		u.InitialSalePrice = value
	}
	if u.Flags.Has(0) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field last_sale_date: %w", err)
		}
		u.LastSaleDate = value
	}
	if u.Flags.Has(0) {
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field last_sale_price: %w", err)
		}
		u.LastSalePrice = value
	}
	if u.Flags.Has(2) {
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field floor_price: %w", err)
		}
		u.FloorPrice = value
	}
	if u.Flags.Has(3) {
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field average_price: %w", err)
		}
		u.AveragePrice = value
	}
	if u.Flags.Has(4) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field listed_count: %w", err)
		}
		u.ListedCount = value
	}
	if u.Flags.Has(5) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field fragment_listed_count: %w", err)
		}
		u.FragmentListedCount = value
	}
	if u.Flags.Has(5) {
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode payments.uniqueStarGiftValueInfo#512fe446: field fragment_listed_url: %w", err)
		}
		u.FragmentListedURL = value
	}
	return nil
}

// SetLastSaleOnFragment sets value of LastSaleOnFragment conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetLastSaleOnFragment(value bool) {
	if value {
		u.Flags.Set(1)
		u.LastSaleOnFragment = true
	} else {
		u.Flags.Unset(1)
		u.LastSaleOnFragment = false
	}
}

// GetLastSaleOnFragment returns value of LastSaleOnFragment conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) GetLastSaleOnFragment() (value bool) {
	if u == nil {
		return
	}
	return u.Flags.Has(1)
}

// SetValueIsAverage sets value of ValueIsAverage conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetValueIsAverage(value bool) {
	if value {
		u.Flags.Set(6)
		u.ValueIsAverage = true
	} else {
		u.Flags.Unset(6)
		u.ValueIsAverage = false
	}
}

// GetValueIsAverage returns value of ValueIsAverage conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) GetValueIsAverage() (value bool) {
	if u == nil {
		return
	}
	return u.Flags.Has(6)
}

// GetCurrency returns value of Currency field.
func (u *PaymentsUniqueStarGiftValueInfo) GetCurrency() (value string) {
	if u == nil {
		return
	}
	return u.Currency
}

// GetValue returns value of Value field.
func (u *PaymentsUniqueStarGiftValueInfo) GetValue() (value int64) {
	if u == nil {
		return
	}
	return u.Value
}

// GetInitialSaleDate returns value of InitialSaleDate field.
func (u *PaymentsUniqueStarGiftValueInfo) GetInitialSaleDate() (value int) {
	if u == nil {
		return
	}
	return u.InitialSaleDate
}

// GetInitialSaleStars returns value of InitialSaleStars field.
func (u *PaymentsUniqueStarGiftValueInfo) GetInitialSaleStars() (value int64) {
	if u == nil {
		return
	}
	return u.InitialSaleStars
}

// GetInitialSalePrice returns value of InitialSalePrice field.
func (u *PaymentsUniqueStarGiftValueInfo) GetInitialSalePrice() (value int64) {
	if u == nil {
		return
	}
	return u.InitialSalePrice
}

// SetLastSaleDate sets value of LastSaleDate conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetLastSaleDate(value int) {
	u.Flags.Set(0)
	u.LastSaleDate = value
}

// GetLastSaleDate returns value of LastSaleDate conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetLastSaleDate() (value int, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(0) {
		return value, false
	}
	return u.LastSaleDate, true
}

// SetLastSalePrice sets value of LastSalePrice conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetLastSalePrice(value int64) {
	u.Flags.Set(0)
	u.LastSalePrice = value
}

// GetLastSalePrice returns value of LastSalePrice conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetLastSalePrice() (value int64, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(0) {
		return value, false
	}
	return u.LastSalePrice, true
}

// SetFloorPrice sets value of FloorPrice conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetFloorPrice(value int64) {
	u.Flags.Set(2)
	u.FloorPrice = value
}

// GetFloorPrice returns value of FloorPrice conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetFloorPrice() (value int64, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(2) {
		return value, false
	}
	return u.FloorPrice, true
}

// SetAveragePrice sets value of AveragePrice conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetAveragePrice(value int64) {
	u.Flags.Set(3)
	u.AveragePrice = value
}

// GetAveragePrice returns value of AveragePrice conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetAveragePrice() (value int64, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(3) {
		return value, false
	}
	return u.AveragePrice, true
}

// SetListedCount sets value of ListedCount conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetListedCount(value int) {
	u.Flags.Set(4)
	u.ListedCount = value
}

// GetListedCount returns value of ListedCount conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetListedCount() (value int, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(4) {
		return value, false
	}
	return u.ListedCount, true
}

// SetFragmentListedCount sets value of FragmentListedCount conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetFragmentListedCount(value int) {
	u.Flags.Set(5)
	u.FragmentListedCount = value
}

// GetFragmentListedCount returns value of FragmentListedCount conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetFragmentListedCount() (value int, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(5) {
		return value, false
	}
	return u.FragmentListedCount, true
}

// SetFragmentListedURL sets value of FragmentListedURL conditional field.
func (u *PaymentsUniqueStarGiftValueInfo) SetFragmentListedURL(value string) {
	u.Flags.Set(5)
	u.FragmentListedURL = value
}

// GetFragmentListedURL returns value of FragmentListedURL conditional field and
// boolean which is true if field was set.
func (u *PaymentsUniqueStarGiftValueInfo) GetFragmentListedURL() (value string, ok bool) {
	if u == nil {
		return
	}
	if !u.Flags.Has(5) {
		return value, false
	}
	return u.FragmentListedURL, true
}
