//go:build integration

package inttest

import (
	"context"
	"errors"
	"testing"

	"github.com/google/uuid"

	"scrabble/backend/internal/game"
)

// TestHideFinishedGame covers per-account game hiding: an active game cannot be
// hidden, a finished game is removed from the hider's own list while staying visible to the
// other player, an outsider cannot hide it, and the action is idempotent.
func TestHideFinishedGame(t *testing.T) {
	ctx := context.Background()
	svc, gameID, seats, _ := newDraftGame(t)

	// Hiding while the game is still active is refused.
	if err := svc.HideGame(ctx, seats[0], gameID); !errors.Is(err, game.ErrGameActive) {
		t.Fatalf("hide active = %v, want ErrGameActive", err)
	}

	// Finish the game by seat 0 resigning.
	if _, err := svc.Resign(ctx, gameID, seats[0]); err != nil {
		t.Fatalf("resign: %v", err)
	}

	// A non-player cannot hide it.
	if err := svc.HideGame(ctx, provisionAccount(t), gameID); !errors.Is(err, game.ErrNotAPlayer) {
		t.Fatalf("hide by outsider = %v, want ErrNotAPlayer", err)
	}

	// Seat 0 hides the finished game; hiding again is a no-op success.
	if err := svc.HideGame(ctx, seats[0], gameID); err != nil {
		t.Fatalf("hide: %v", err)
	}
	if err := svc.HideGame(ctx, seats[0], gameID); err != nil {
		t.Fatalf("hide twice: %v", err)
	}

	// It is gone from seat 0's list but still in seat 1's (hiding is per-account).
	if containsGame(t, svc, seats[0], gameID) {
		t.Error("hidden game still listed for the hider")
	}
	if !containsGame(t, svc, seats[1], gameID) {
		t.Error("hidden game should remain listed for the other player")
	}
}

// containsGame reports whether the account's lobby list includes gameID.
func containsGame(t *testing.T, svc *game.Service, accountID, gameID uuid.UUID) bool {
	t.Helper()
	games, err := svc.ListForAccount(context.Background(), accountID)
	if err != nil {
		t.Fatalf("list for account: %v", err)
	}
	for _, g := range games {
		if g.ID == gameID {
			return true
		}
	}
	return false
}
