package human_test

import (
	"context"
	"os"
	"testing"

	"github.com/flowy-live/llink/internal/human"
	"github.com/flowy-live/llink/internal/testhelper"
	"github.com/jackc/pgx/v5/pgxpool"
	"github.com/stretchr/testify/assert"
)

var dbPool *pgxpool.Pool

func TestMain(m *testing.M) {
	dbPool = testhelper.SetupTestDB()
	defer testhelper.TeardownTestDB()

	ret := m.Run()
	os.Exit(ret)
}

func TestHumanService(t *testing.T) {
	ctx := context.Background()
	svc := human.NewService(dbPool)

	// Test GetByEmail with non-existent email
	_, err := svc.GetByEmail(ctx, "newuser@example.com")
	assert.Error(t, err)
	assert.ErrorIs(t, err, human.ErrNotFound)

	// Test GetOrCreateByEmail creates new human
	createdHuman, err := svc.GetOrCreateByEmail(ctx, "newuser@example.com")
	assert.NoError(t, err)
	assert.NotEmpty(t, createdHuman.ID)
	assert.Equal(t, "newuser@example.com", createdHuman.Email)
	assert.Equal(t, "newuser", createdHuman.EmailPrefix)
	assert.NotZero(t, createdHuman.CreatedAt)

	// Test GetOrCreateByEmail returns existing human
	existingHuman, err := svc.GetOrCreateByEmail(ctx, "newuser@example.com")
	assert.NoError(t, err)
	assert.Equal(t, createdHuman.ID, existingHuman.ID)
	assert.Equal(t, createdHuman.Email, existingHuman.Email)

	// Test GetByEmail with existing email
	foundHuman, err := svc.GetByEmail(ctx, "newuser@example.com")
	assert.NoError(t, err)
	assert.Equal(t, createdHuman.ID, foundHuman.ID)
	assert.Equal(t, createdHuman.Email, foundHuman.Email)

	// Test with another email
	anotherHuman, err := svc.GetOrCreateByEmail(ctx, "another@example.com")
	assert.NoError(t, err)
	assert.NotEqual(t, createdHuman.ID, anotherHuman.ID)
	assert.Equal(t, "another@example.com", anotherHuman.Email)
	assert.Equal(t, "another", anotherHuman.EmailPrefix)
}
