package model

import (
	"errors"
	"testing"
	"time"

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

func TestListCloudOrganizationUpdatedAtBatchesLargeInputs(t *testing.T) {
	const uniqueCount = 65_536
	const expectedCalls = (uniqueCount + organizationSyncStateBatchSize - 1) / organizationSyncStateBatchSize
	ids := make([]uint, 0, uniqueCount+2)
	for id := uint(1); id <= uniqueCount; id++ {
		ids = append(ids, id)
	}
	ids = append(ids, 1, organizationSyncStateBatchSize+1)

	var calls int
	var loadedIDs []uint
	updatedAt := time.Date(2026, time.August, 25, 4, 0, 0, 0, time.UTC)
	result, err := listCloudOrganizationUpdatedAt(ids, func(batch []uint) ([]organizationSyncState, error) {
		calls++
		assert.LessOrEqual(t, len(batch), organizationSyncStateBatchSize)
		loadedIDs = append(loadedIDs, batch...)
		return []organizationSyncState{{
			ID:         uint(calls),
			DbaasOrgID: batch[0],
			UpdatedAt:  updatedAt,
		}}, nil
	})

	require.NoError(t, err)
	assert.Equal(t, expectedCalls, calls)
	assert.Len(t, loadedIDs, uniqueCount)
	for i, id := range loadedIDs {
		assert.Equal(t, uint(i+1), id)
	}
	assert.Len(t, result, calls)
}

func TestListCloudOrganizationUpdatedAtReturnsBatchError(t *testing.T) {
	expectedErr := errors.New("load sync state")
	ids := make([]uint, organizationSyncStateBatchSize+1)
	for i := range ids {
		ids[i] = uint(i + 1)
	}

	var calls int
	result, err := listCloudOrganizationUpdatedAt(ids, func(batch []uint) ([]organizationSyncState, error) {
		calls++
		if calls == 2 {
			return nil, expectedErr
		}
		return []organizationSyncState{{
			ID:         1,
			DbaasOrgID: batch[0],
			UpdatedAt:  time.Now(),
		}}, nil
	})

	assert.ErrorIs(t, err, expectedErr)
	assert.Nil(t, result)
	assert.Equal(t, 2, calls)
}
