package user_test

import (
	"context"
	"testing"

	userdomain "hyapp/services/user-service/internal/domain/user"
	"hyapp/services/user-service/internal/testutil/mysqltest"
)

func TestFindInviteReferrerByCodeDoesNotAmbiguouslySelectUserProjection(t *testing.T) {
	repo := mysqltest.NewRepository(t)
	ctx := context.Background()

	createInviteReferrerUser(t, repo, 12001, "166001", 1000)
	inviter, err := repo.GetUser(ctx, 12001)
	if err != nil {
		t.Fatalf("get inviter failed: %v", err)
	}
	if inviter.InviteOverview.MyInviteCode == "" {
		t.Fatalf("expected inviter primary invite code")
	}

	found, err := repo.FindInviteReferrerByCode(ctx, "lalu", inviter.InviteOverview.MyInviteCode)
	if err != nil {
		t.Fatalf("find invite referrer by code failed: %v", err)
	}
	if found.UserID != inviter.UserID {
		t.Fatalf("invite referrer mismatch: got=%d want=%d", found.UserID, inviter.UserID)
	}
}

func TestBindInviteReferrerAllowsDifferentCountryInSameRegion(t *testing.T) {
	repo := mysqltest.NewRepository(t)
	ctx := context.Background()

	createInviteReferrerUserInRegion(t, repo, 12011, "166011", "AT", 3, 1000)
	createInviteReferrerUserInRegion(t, repo, 12012, "166012", "SG", 3, 1001)
	inviter, err := repo.GetUser(ctx, 12011)
	if err != nil {
		t.Fatalf("get inviter failed: %v", err)
	}

	updated, err := repo.BindInviteReferrer(ctx, userdomain.BindInviteReferrerCommand{
		AppCode:       "lalu",
		InvitedUserID: 12012,
		InviteCode:    inviter.InviteOverview.MyInviteCode,
		RequestID:     "req-same-region-bind",
		BoundAtMs:     2000,
	})
	if err != nil {
		t.Fatalf("bind invite referrer in same region failed: %v", err)
	}
	if !updated.InviteBinding.Bound || updated.InviteBinding.InviterUserID != 12011 {
		t.Fatalf("same-region invite binding mismatch: %+v", updated.InviteBinding)
	}

	attribution, err := repo.GetInviteAttribution(ctx, 12012)
	if err != nil {
		t.Fatalf("get invite attribution failed: %v", err)
	}
	if !attribution.Found || attribution.InviterUserID != 12011 || attribution.InviteCode != inviter.InviteOverview.MyInviteCode {
		t.Fatalf("same-region attribution mismatch: %+v", attribution)
	}
}

func createInviteReferrerUser(t *testing.T, repo *mysqltest.Repository, userID int64, displayUserID string, nowMs int64) {
	t.Helper()
	createInviteReferrerUserInRegion(t, repo, userID, displayUserID, "SG", 3, nowMs)
}

func createInviteReferrerUserInRegion(t *testing.T, repo *mysqltest.Repository, userID int64, displayUserID string, country string, regionID int64, nowMs int64) {
	t.Helper()
	err := repo.CreateUserWithIdentity(context.Background(), userdomain.User{
		AppCode:                  "lalu",
		UserID:                   userID,
		DefaultDisplayUserID:     displayUserID,
		CurrentDisplayUserID:     displayUserID,
		CurrentDisplayUserIDKind: userdomain.DisplayUserIDKindDefault,
		Username:                 "invite-referrer",
		Gender:                   "male",
		Country:                  country,
		RegionID:                 regionID,
		ProfileCompleted:         true,
		ProfileCompletedAtMs:     nowMs,
		Status:                   userdomain.StatusActive,
		OnboardingStatus:         userdomain.OnboardingStatusCompleted,
		CreatedAtMs:              nowMs,
		UpdatedAtMs:              nowMs,
	}, userdomain.Identity{
		AppCode:              "lalu",
		UserID:               userID,
		DisplayUserID:        displayUserID,
		DefaultDisplayUserID: displayUserID,
		DisplayUserIDKind:    userdomain.DisplayUserIDKindDefault,
		Status:               userdomain.DisplayUserIDStatusActive,
	})
	if err != nil {
		t.Fatalf("create invite referrer user %d failed: %v", userID, err)
	}
}
