package repo_imp

import (
	"context"
	"regexp"
	"testing"
	"time"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/stretchr/testify/require"
	pkgdb "github.com/tidbcloud/pkgv2/db"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	"github.com/tidbcloud/serverless-service/internal/domain/repo"
	gormmysql "gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func newBranchRepoForTest(t *testing.T) (repo.BranchRepo, sqlmock.Sqlmock) {
	t.Helper()
	sqlDB, mock, err := sqlmock.New()
	require.NoError(t, err)
	t.Cleanup(func() {
		mock.ExpectClose()
		require.NoError(t, sqlDB.Close())
		require.NoError(t, mock.ExpectationsWereMet())
	})

	gormDB, err := gorm.Open(gormmysql.New(gormmysql.Config{
		Conn:                      sqlDB,
		SkipInitializeWithVersion: true,
	}), &gorm.Config{})
	require.NoError(t, err)
	return NewBranchRepoImp(pkgdb.NewProvider(gormDB)), mock
}

func TestListBranchesByFilterCreatedAtBounds(t *testing.T) {
	cutoff := time.Date(2026, 9, 4, 12, 0, 0, 0, time.UTC)
	statuses := []constant.BranchStatus{
		constant.BranchStatusPending,
		constant.BranchStatusCreating,
		constant.BranchStatusRestoring,
	}

	t.Run("created after is exclusive", func(t *testing.T) {
		branchRepo, mock := newBranchRepoForTest(t)
		mock.ExpectQuery(regexp.QuoteMeta(
			"SELECT * FROM `branches` WHERE status in (?,?,?) AND created_at > ?",
		)).WithArgs(statuses[0], statuses[1], statuses[2], cutoff).
			WillReturnRows(sqlmock.NewRows([]string{"id"}))

		_, bizErr := branchRepo.ListBranchesByFilter(context.Background(), repo.BranchFilter{
			Statuses:     statuses,
			CreatedAfter: &cutoff,
		})

		require.Nil(t, bizErr)
		require.NoError(t, mock.ExpectationsWereMet())
	})

	t.Run("created at or before is inclusive", func(t *testing.T) {
		branchRepo, mock := newBranchRepoForTest(t)
		mock.ExpectQuery(regexp.QuoteMeta(
			"SELECT * FROM `branches` WHERE status in (?,?,?) AND created_at <= ?",
		)).WithArgs(statuses[0], statuses[1], statuses[2], cutoff).
			WillReturnRows(sqlmock.NewRows([]string{"id"}))

		_, bizErr := branchRepo.ListBranchesByFilter(context.Background(), repo.BranchFilter{
			Statuses:          statuses,
			CreatedAtOrBefore: &cutoff,
		})

		require.Nil(t, bizErr)
		require.NoError(t, mock.ExpectationsWereMet())
	})
}
