//go:build integration

package inttest

import (
	"fmt"
	"net/http"
	"testing"
	"time"

	"go.uber.org/zap/zaptest"

	"scrabble/backend/internal/account"
	"scrabble/backend/internal/server"
)

// TestVariantPreferenceGate covers the New Game gate: a player may start a quick game
// or create a friend invitation only in a variant they have enabled in their profile
// (a fresh account defaults to the two Russian-alphabet games), and any other variant is
// refused with 400. The complementary case — an invited friend accepting an invitation in
// a variant they have NOT enabled — is exercised by TestGameLimitGate, where a
// default-preference human accepts an English invitation over HTTP.
func TestVariantPreferenceGate(t *testing.T) {
	clearOpenGames(t)
	srv := server.New(":0", server.Deps{
		Logger:      zaptest.NewLogger(t),
		DB:          testDB,
		Accounts:    account.NewStore(testDB),
		Games:       newGameService(),
		Matchmaker:  newMatchmaker(t, newRobotService(t, newGameService()), time.Minute, 0),
		Invitations: newInvitationService(),
	})

	human := provisionAccount(t) // default preferences: erudit_ru only
	opp := provisionAccount(t)

	// A variant outside the player's preferences is refused on both create paths.
	if rec := userPost(t, srv, "/api/v1/user/lobby/enqueue", human, `{"variant":"scrabble_en"}`); rec.Code != http.StatusBadRequest {
		t.Fatalf("enqueue non-preferred variant = %d (%s), want 400", rec.Code, rec.Body.String())
	}
	invBody := fmt.Sprintf(`{"variant":"scrabble_en","invitee_ids":[%q]}`, opp.String())
	if rec := userPost(t, srv, "/api/v1/user/invitations", human, invBody); rec.Code != http.StatusBadRequest {
		t.Fatalf("invitation non-preferred variant = %d (%s), want 400", rec.Code, rec.Body.String())
	}

	// The default-enabled variant (Erudit) is allowed: the quick enqueue opens a game.
	if rec := userPost(t, srv, "/api/v1/user/lobby/enqueue", human, `{"variant":"erudit_ru"}`); rec.Code != http.StatusOK {
		t.Fatalf("enqueue preferred variant = %d (%s), want 200", rec.Code, rec.Body.String())
	}
	clearOpenGames(t)
}
