//go:build integration

package inttest

import (
	"context"
	"net/http"
	"net/http/httptest"
	"slices"
	"strings"
	"testing"

	"github.com/google/uuid"
	"go.uber.org/zap/zaptest"

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

// TestTelegramAuthSeedsPromoVariantForNewUserOnly drives the sessions/telegram endpoint
// to confirm a promo deep-link start-param seeds a brand-new account's variant
// preferences (English Scrabble alongside the default Erudit), that a new account with no
// such payload keeps the Erudit-only default, and that an existing account is never
// re-seeded on a later login (the new-user-only contract).
func TestTelegramAuthSeedsPromoVariantForNewUserOnly(t *testing.T) {
	srv := server.New(":0", server.Deps{
		Logger:   zaptest.NewLogger(t),
		DB:       testDB,
		Accounts: account.NewStore(testDB),
		Sessions: session.NewService(session.NewStore(testDB), session.NewCache()),
		Notifier: &captureNotifier{},
	})
	h := srv.Handler()

	post := func(ext, startParam string) {
		body := `{"external_id":"` + ext + `","language_code":"en","first_name":"Promo"`
		if startParam != "" {
			body += `,"start_param":"` + startParam + `"`
		}
		body += `}`
		rec := httptest.NewRecorder()
		req := httptest.NewRequest(http.MethodPost, "/api/v1/internal/sessions/telegram", strings.NewReader(body))
		req.Header.Set("Content-Type", "application/json")
		h.ServeHTTP(rec, req)
		if rec.Code != http.StatusOK {
			t.Fatalf("telegram auth = %d: %s", rec.Code, rec.Body.String())
		}
	}
	store := account.NewStore(testDB)
	reload := func(ext string) []string {
		acc, err := store.AccountByIdentity(context.Background(), account.KindTelegram, ext)
		if err != nil {
			t.Fatalf("lookup %s: %v", ext, err)
		}
		return acc.VariantPreferences
	}

	// A brand-new account reached through a promo deep-link is seeded with English
	// Scrabble alongside the default Erudit.
	promoExt := "tg-" + uuid.NewString()
	post(promoExt, "verudit_ru-scrabble_en")
	if got, want := reload(promoExt), []string{"erudit_ru", "scrabble_en"}; !slices.Equal(got, want) {
		t.Errorf("promo new account variants = %v, want %v", got, want)
	}

	// A brand-new account with no promo payload keeps the Erudit-only default.
	plainExt := "tg-" + uuid.NewString()
	post(plainExt, "")
	if got, want := reload(plainExt), []string{"erudit_ru"}; !slices.Equal(got, want) {
		t.Errorf("plain new account variants = %v, want %v", got, want)
	}

	// A later login of the promo account, even via a different payload, must not re-seed:
	// the seed is first-contact only.
	post(promoExt, "vscrabble_ru")
	if got, want := reload(promoExt), []string{"erudit_ru", "scrabble_en"}; !slices.Equal(got, want) {
		t.Errorf("existing account re-seeded = %v, want unchanged %v", got, want)
	}
}
