package repository

import (
	"baron-sso-backend/internal/domain"
	"context"
	"testing"

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

func TestClearOrphanUserTenantMemberships(t *testing.T) {
	ctx := context.Background()
	repo := NewUserRepository(testDB)
	tenantRepo := NewTenantRepository(testDB)

	require.NoError(t, testDB.Exec("DELETE FROM user_login_ids").Error)
	require.NoError(t, testDB.Exec("DELETE FROM users").Error)
	require.NoError(t, testDB.Exec("DELETE FROM tenant_domains").Error)
	require.NoError(t, testDB.Unscoped().Where("slug IN ?", []string{"orphan-active", "orphan-deleted"}).Delete(&domain.Tenant{}).Error)

	activeTenant := &domain.Tenant{Name: "Active Tenant", Slug: "orphan-active", Type: domain.TenantTypeCompany}
	deletedTenant := &domain.Tenant{Name: "Deleted Tenant", Slug: "orphan-deleted", Type: domain.TenantTypeCompany}
	require.NoError(t, tenantRepo.Create(ctx, activeTenant))
	require.NoError(t, tenantRepo.Create(ctx, deletedTenant))
	require.NoError(t, testDB.Delete(&domain.Tenant{}, "id = ?", deletedTenant.ID).Error)

	activeUser := &domain.User{
		Email:    "active-membership@example.com",
		Name:     "Active Membership",
		Role:     "user",
		TenantID: &activeTenant.ID,
	}
	orphanUser := &domain.User{
		Email:    "orphan-membership@example.com",
		Name:     "Orphan Membership",
		Role:     "user",
		TenantID: &deletedTenant.ID,
	}
	require.NoError(t, repo.Create(ctx, activeUser))
	require.NoError(t, repo.Create(ctx, orphanUser))

	count, err := CountOrphanUserTenantMemberships(ctx, testDB)
	require.NoError(t, err)
	assert.Equal(t, int64(1), count)

	affected, err := ClearOrphanUserTenantMemberships(ctx, testDB)
	require.NoError(t, err)
	assert.Equal(t, int64(1), affected)

	foundActive, err := repo.FindByEmail(ctx, activeUser.Email)
	require.NoError(t, err)
	require.NotNil(t, foundActive.TenantID)
	require.NotNil(t, foundActive.Tenant)
	assert.Equal(t, activeTenant.ID, *foundActive.TenantID)

	foundOrphan, err := repo.FindByEmail(ctx, orphanUser.Email)
	require.NoError(t, err)
	assert.Nil(t, foundOrphan.TenantID)

	count, err = CountOrphanUserTenantMemberships(ctx, testDB)
	require.NoError(t, err)
	assert.Equal(t, int64(0), count)
}
