//go:build integration

package inttest

import (
	"context"
	"testing"
	"time"

	"github.com/google/uuid"

	"scrabble/backend/internal/engine"
	"scrabble/backend/internal/game"
)

// TestMultiplayerTimeoutContinues drives a three-player game through the domain:
// the first timeout drops a seat but the game plays on, and the second leaves a
// sole survivor who wins. Empty away windows make the timeouts deterministic.
func TestMultiplayerTimeoutContinues(t *testing.T) {
	ctx := context.Background()
	svc := newGameService()
	seats := []uuid.UUID{provisionAccount(t), provisionAccount(t), provisionAccount(t)}
	for _, s := range seats {
		setAway(t, s, "UTC", "00:00", "00:00") // empty window → no away grace
	}
	g, err := svc.Create(ctx, game.CreateParams{
		Variant: engine.VariantEnglish, Seats: seats, TurnTimeout: time.Hour, Seed: 42,
	})
	if err != nil {
		t.Fatalf("create: %v", err)
	}
	if g.Players != 3 {
		t.Fatalf("players = %d, want 3", g.Players)
	}

	// Seat 0 (to move) goes overdue. It times out, but two seats remain, so the
	// game continues and the turn advances off the dropped seat.
	backdate(t, g.ID, time.Now().UTC().Add(-2*time.Hour))
	if _, err := svc.SweepTimeouts(ctx, time.Now().UTC()); err != nil {
		t.Fatalf("first sweep: %v", err)
	}
	h, err := svc.History(ctx, g.ID)
	if err != nil {
		t.Fatalf("history: %v", err)
	}
	if h.Game.Status != game.StatusActive {
		t.Fatalf("a three-player game must continue after one timeout, status %q", h.Game.Status)
	}
	if h.Game.ToMove == 0 {
		t.Errorf("to-move should advance off the timed-out seat 0, got %d", h.Game.ToMove)
	}

	// The next seat to move also times out, leaving a single active seat: the game
	// finishes and the sole survivor wins.
	backdate(t, g.ID, time.Now().UTC().Add(-2*time.Hour))
	if _, err := svc.SweepTimeouts(ctx, time.Now().UTC()); err != nil {
		t.Fatalf("second sweep: %v", err)
	}
	h2, err := svc.History(ctx, g.ID)
	if err != nil {
		t.Fatalf("history 2: %v", err)
	}
	if h2.Game.Status != game.StatusFinished || h2.Game.EndReason != "timeout" {
		t.Fatalf("game should finish on the second timeout: status %q reason %q", h2.Game.Status, h2.Game.EndReason)
	}
	winners := 0
	for _, s := range h2.Game.Seats {
		if s.IsWinner {
			winners++
		}
	}
	if winners != 1 {
		t.Errorf("want exactly one surviving winner, got %d", winners)
	}
}
