package ledger

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestParseCursor(t *testing.T) {
	t.Run("ValidCursor", func(t *testing.T) {
		cursor := encodeCursor(100)
		offset, err := parseCursor(cursor)

		require.NoError(t, err)
		assert.Equal(t, 100, offset)
	})

	t.Run("ZeroOffset", func(t *testing.T) {
		cursor := encodeCursor(0)
		offset, err := parseCursor(cursor)

		require.NoError(t, err)
		assert.Equal(t, 0, offset)
	})

	t.Run("InvalidBase64", func(t *testing.T) {
		_, err := parseCursor("not-valid-base64!!!")
		require.Error(t, err)
		assert.Contains(t, err.Error(), "invalid base64")
	})

	t.Run("InvalidFormat", func(t *testing.T) {
		// Encode something that's not in the expected format
		invalidCursor := "aW52YWxpZC1mb3JtYXQ=" // base64 of "invalid-format"
		_, err := parseCursor(invalidCursor)

		require.Error(t, err)
		assert.Contains(t, err.Error(), "invalid cursor format")
	})

	t.Run("InvalidOffsetValue", func(t *testing.T) {
		// Create a cursor with non-numeric offset
		invalidCursor := "b2Zmc2V0OmFiYw==" // base64 of "offset:abc"
		_, err := parseCursor(invalidCursor)

		require.Error(t, err)
		assert.Contains(t, err.Error(), "invalid offset")
	})

	t.Run("NegativeOffset", func(t *testing.T) {
		cursor := encodeCursor(-10)
		offset, err := parseCursor(cursor)

		require.NoError(t, err)
		assert.Equal(t, -10, offset)
	})
}

func TestEncodeCursor(t *testing.T) {
	t.Run("PositiveOffset", func(t *testing.T) {
		cursor := encodeCursor(100)
		assert.NotEmpty(t, cursor)

		// Verify it can be parsed back
		offset, err := parseCursor(cursor)
		require.NoError(t, err)
		assert.Equal(t, 100, offset)
	})

	t.Run("ZeroOffset", func(t *testing.T) {
		cursor := encodeCursor(0)
		assert.NotEmpty(t, cursor)

		offset, err := parseCursor(cursor)
		require.NoError(t, err)
		assert.Equal(t, 0, offset)
	})

	t.Run("LargeOffset", func(t *testing.T) {
		cursor := encodeCursor(999999)
		assert.NotEmpty(t, cursor)

		offset, err := parseCursor(cursor)
		require.NoError(t, err)
		assert.Equal(t, 999999, offset)
	})

	t.Run("RoundTrip", func(t *testing.T) {
		testOffsets := []int{0, 1, 10, 50, 100, 500, 1000, 10000}

		for _, expected := range testOffsets {
			cursor := encodeCursor(expected)
			actual, err := parseCursor(cursor)
			require.NoError(t, err)
			assert.Equal(t, expected, actual)
		}
	})
}
