//go:build integration

package inttest

import (
	"context"
	"testing"

	"scrabble/backend/internal/game"
)

// TestDraftPersistAndConflictReset covers draft persistence: a round-trip of the
// rack order + board tiles, the actor's own draft cleared on their move, and an opponent's
// board draft reset when a committed play overlaps one of its cells (the rack order kept).
func TestDraftPersistAndConflictReset(t *testing.T) {
	ctx := context.Background()
	svc, gameID, seats, hint := newDraftGame(t)

	// Round-trip seat 0's rack order + a board draft.
	d0 := game.Draft{RackOrder: "QANIWE?", BoardTiles: []game.DraftTile{{Row: 1, Col: 1, Letter: "Q"}}}
	if err := svc.SaveDraft(ctx, gameID, seats[0], d0); err != nil {
		t.Fatalf("save draft 0: %v", err)
	}
	if got, err := svc.GetDraft(ctx, gameID, seats[0]); err != nil ||
		got.RackOrder != "QANIWE?" || len(got.BoardTiles) != 1 || got.BoardTiles[0].Letter != "Q" {
		t.Fatalf("get draft 0 = %+v (err %v)", got, err)
	}

	// Seat 1 drafts a board tile on a cell the opening play will commit.
	overlap := hint.Tiles[0]
	if err := svc.SaveDraft(ctx, gameID, seats[1], game.Draft{
		RackOrder:  "ABCDEFG",
		BoardTiles: []game.DraftTile{{Row: overlap.Row, Col: overlap.Col, Letter: "X"}},
	}); err != nil {
		t.Fatalf("save draft 1: %v", err)
	}

	if _, err := svc.SubmitPlay(ctx, gameID, seats[0], hint.Tiles); err != nil {
		t.Fatalf("seat0 play: %v", err)
	}

	// Seat 0's own draft is cleared by their move.
	if d, _ := svc.GetDraft(ctx, gameID, seats[0]); d.RackOrder != "" || len(d.BoardTiles) != 0 {
		t.Errorf("actor draft not cleared: %+v", d)
	}
	// Seat 1's board draft overlapped the play and is reset; the rack order is kept.
	if d, _ := svc.GetDraft(ctx, gameID, seats[1]); len(d.BoardTiles) != 0 || d.RackOrder != "ABCDEFG" {
		t.Errorf("conflicting draft not reset (or rack order lost): %+v", d)
	}
}

// TestDraftSurvivesNonConflictingMove checks an opponent's board draft is kept when a
// committed play does not touch any of its cells.
func TestDraftSurvivesNonConflictingMove(t *testing.T) {
	ctx := context.Background()
	svc, gameID, seats, hint := newDraftGame(t)

	// Seat 1 drafts a far corner tile the central opening play cannot reach.
	if err := svc.SaveDraft(ctx, gameID, seats[1], game.Draft{
		BoardTiles: []game.DraftTile{{Row: 0, Col: 0, Letter: "Z"}},
	}); err != nil {
		t.Fatalf("save draft 1: %v", err)
	}
	if _, err := svc.SubmitPlay(ctx, gameID, seats[0], hint.Tiles); err != nil {
		t.Fatalf("seat0 play: %v", err)
	}
	if d, _ := svc.GetDraft(ctx, gameID, seats[1]); len(d.BoardTiles) != 1 || d.BoardTiles[0].Letter != "Z" {
		t.Errorf("non-conflicting draft should survive: %+v", d)
	}
}

// TestSaveDraftRejectsOutsider checks only a seated player may save a draft.
func TestSaveDraftRejectsOutsider(t *testing.T) {
	ctx := context.Background()
	svc, gameID, _, _ := newDraftGame(t)
	if err := svc.SaveDraft(ctx, gameID, provisionAccount(t), game.Draft{RackOrder: "X"}); err == nil {
		t.Fatal("outsider SaveDraft should fail")
	}
}
