package changefeed

import (
	"encoding/base64"
	"encoding/json"
	"math"

	"github.com/tidbcloud/pkgv2/bizerr"
)

type listPageToken struct {
	Page uint32 `json:"page"`
}

// encodePageToken encodes the page number into an opaque base64url(JSON) token.
func encodePageToken(page uint32) (string, error) {
	p := listPageToken{Page: page}
	b, err := json.Marshal(p)
	if err != nil {
		return "", err
	}
	// Use RawURLEncoding to produce URL-safe base64 without padding.
	return base64.RawURLEncoding.EncodeToString(b), nil
}

// decodePageToken decodes the opaque token into a page number.
// An empty token returns page 1. On error, returns an error prefixed with "invalid page_token:".
func decodePageToken(token string) (uint32, error) {
	if token == "" {
		return 1, nil
	}

	b, err := base64.RawURLEncoding.DecodeString(token)
	if err != nil {
		return 0, bizerr.New(bizerr.ErrCodeParams, "invalid page_token: %v", err)
	}
	var p listPageToken
	if err := json.Unmarshal(b, &p); err != nil {
		return 0, bizerr.New(bizerr.ErrCodeParams, "invalid page_token: %v", err)
	}
	if p.Page == math.MaxUint32 || p.Page == 0 {
		return 0, bizerr.New(bizerr.ErrCodeParams, "invalid page_token: page out of range")
	}

	return p.Page, nil
}
