package pagetoken

import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"strings"
)

type PageToken[T any] struct {
	Prev T
}

func (pt *PageToken[T]) EncodeToString() (string, error) {
	prev, err := json.Marshal(pt.Prev)
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("prev:%s", prev))), nil
}

func (pt *PageToken[T]) DecodeFromString(pageToken string) error {
	decoded, err := base64.StdEncoding.DecodeString(pageToken)
	if err != nil {
		return err
	}
	parts := strings.Split(string(decoded), ":")
	if len(parts) != 2 {
		return errors.New("bad page token length")
	} else if parts[0] != "prev" {
		return errors.New("bad page token prefix")
	}
	prev := new(T)
	if err := json.Unmarshal([]byte(parts[1]), prev); err != nil {
		return err
	}
	pt.Prev = *prev
	return nil
}
