package tenancy

import (
	"context"
	"testing"

	"bookra/apps/backend/internal/db"
	"bookra/apps/backend/internal/domain"
)

func TestBootstrapResolvesMembershipAfterIdentitySync(t *testing.T) {
	repo := db.NewMemoryRepository()
	service := NewService(repo)

	if err := repo.EnsureUserIdentity(context.Background(), "neon-user-123", "owner@bookra.dev", "Neon Owner"); err != nil {
		t.Fatalf("ensure user identity: %v", err)
	}

	bootstrap, err := service.Bootstrap(context.Background(), domain.Principal{
		Subject: "neon-user-123",
		Email:   "owner@bookra.dev",
		Name:    "Neon Owner",
		Role:    "authenticated",
	})
	if err != nil {
		t.Fatalf("bootstrap: %v", err)
	}

	if bootstrap.TenantID == "" {
		t.Fatal("expected tenant id")
	}
	if bootstrap.CurrentUser.Role != "owner" {
		t.Fatalf("expected owner role, got %s", bootstrap.CurrentUser.Role)
	}
	if bootstrap.CurrentUser.Name != "Neon Owner" {
		t.Fatalf("expected synced name, got %s", bootstrap.CurrentUser.Name)
	}
}

func TestBootstrapReturnsShellWhenMembershipMissing(t *testing.T) {
	repo := db.NewMemoryRepository()
	service := NewService(repo)

	bootstrap, err := service.Bootstrap(context.Background(), domain.Principal{
		Subject: "unassigned-user",
		Email:   "new@bookra.dev",
		Name:    "New User",
		Role:    "authenticated",
	})
	if err != nil {
		t.Fatalf("bootstrap without membership: %v", err)
	}

	if bootstrap.TenantID != "" {
		t.Fatalf("expected empty tenant id, got %s", bootstrap.TenantID)
	}
	if bootstrap.CurrentUser.Subject != "unassigned-user" {
		t.Fatalf("expected subject passthrough, got %s", bootstrap.CurrentUser.Subject)
	}
}

func TestOnboardCreatesTenantForAuthenticatedUser(t *testing.T) {
	repo := db.NewMemoryRepository()
	service := NewService(repo)

	bootstrap, err := service.Onboard(context.Background(), domain.Principal{
		Subject: "fresh-user",
		Email:   "fresh@bookra.dev",
		Name:    "Fresh User",
		Role:    "authenticated",
	}, domain.OnboardTenantRequest{
		Name:     "Fresh Studio",
		Slug:     "fresh-studio",
		Preset:   "studio",
		Locale:   "cs",
		Timezone: "Europe/Prague",
	})
	if err != nil {
		t.Fatalf("onboard: %v", err)
	}
	if bootstrap.TenantName != "Fresh Studio" {
		t.Fatalf("expected tenant name, got %s", bootstrap.TenantName)
	}
	if bootstrap.CurrentUser.Role != "owner" {
		t.Fatalf("expected owner role, got %s", bootstrap.CurrentUser.Role)
	}
}

func TestOnboardRejectsInvalidSlug(t *testing.T) {
	repo := db.NewMemoryRepository()
	service := NewService(repo)

	_, err := service.Onboard(context.Background(), domain.Principal{
		Subject: "fresh-user",
		Email:   "fresh@bookra.dev",
		Name:    "Fresh User",
		Role:    "authenticated",
	}, domain.OnboardTenantRequest{
		Name:     "Fresh Studio",
		Slug:     "bad slug",
		Preset:   "studio",
		Locale:   "cs",
		Timezone: "Europe/Prague",
	})
	if err != ErrInvalidOnboarding {
		t.Fatalf("expected invalid onboarding, got %v", err)
	}
}
