package persistence

import (
	"context"
	"regexp"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/stretchr/testify/assert"
)

func TestCheckUserExistsByEmail(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	}
	defer db.Close()

	repo := NewUserRepository(db)

	email := "test@example.com"
	// Test Case 1: User exists
	// Builder produces: SELECT 1 FROM `User` WHERE `email` = ? LIMIT 1
	// Note: Builder quotes tables and columns.
	escapedQuery := regexp.QuoteMeta("SELECT 1 FROM `User` WHERE") + " .* " + regexp.QuoteMeta("LIMIT 1")

	mock.ExpectQuery(escapedQuery).WithArgs(email).WillReturnRows(sqlmock.NewRows([]string{"exists"}).AddRow(1))

	exists, err := repo.CheckUserExistsByEmail(context.Background(), email)
	assert.NoError(t, err)
	assert.True(t, exists)

	// Test Case 2: User does not exist
	mock.ExpectQuery(escapedQuery).WithArgs("nonexistent@example.com").WillReturnRows(sqlmock.NewRows([]string{"exists"}))

	exists, err = repo.CheckUserExistsByEmail(context.Background(), "nonexistent@example.com")
	assert.NoError(t, err)
	assert.False(t, exists)
}

func TestCheckUserExistsByID(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	}
	defer db.Close()

	repo := NewUserRepository(db)

	id := "user-123"
	// Test Case: ID exists
	escapedQuery := regexp.QuoteMeta("SELECT 1 FROM `User` WHERE") + " .* " + regexp.QuoteMeta("LIMIT 1")
	mock.ExpectQuery(escapedQuery).WithArgs(id).WillReturnRows(sqlmock.NewRows([]string{"exists"}).AddRow(1))

	exists, err := repo.CheckUserExistsByID(context.Background(), id)
	assert.NoError(t, err)
	assert.True(t, exists)
}

func TestCheckEmailConflict(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	}
	defer db.Close()

	repo := NewUserRepository(db)

	email := "test@example.com"
	excludeID := "user-123"
	// Test Case: Conflict logic
	escapedQuery := regexp.QuoteMeta("SELECT 1 FROM `User` WHERE") + " .* " + regexp.QuoteMeta("LIMIT 1")

	mock.ExpectQuery(escapedQuery).WithArgs(email, excludeID).WillReturnRows(sqlmock.NewRows([]string{"exists"}).AddRow(1))

	exists, err := repo.CheckEmailConflict(context.Background(), email, excludeID)
	assert.NoError(t, err)
	assert.True(t, exists)
}
