package engine

import (
	"testing"

	"gitea.iliadenisov.ru/developer/scrabble-solver/scrabble"
)

// blankCellFlag is the bit board cells set for a blank tile (board.go encoding).
const blankCellFlag byte = 0x80

// TestDecodeBlankPlayAndReplay places "cat" with the C drawn from a blank, then
// checks the decoded record keeps the concrete letter and the blank flag, and
// that ReplayBoard — using only the ruleset, no dictionary — reproduces the
// blank on the board.
func TestDecodeBlankPlayAndReplay(t *testing.T) {
	g := newEnglishGame(t, 1)
	rs := g.rules
	row, col := centre(rs)

	idx := func(s string) byte {
		t.Helper()
		i, err := rs.Alphabet.Index(s)
		if err != nil {
			t.Fatalf("index %q: %v", s, err)
		}
		return i
	}
	ps := []scrabble.Placement{
		{Row: row, Col: col, Letter: idx("c"), Blank: true},
		{Row: row, Col: col + 1, Letter: idx("a")},
		{Row: row, Col: col + 2, Letter: idx("t")},
	}

	move, err := g.solver.ValidatePlay(g.board, scrabble.Horizontal, ps)
	if err != nil {
		t.Fatalf("validate: %v", err)
	}
	rec := g.recordPlay(0, move)

	if rec.Action != ActionPlay || len(rec.Tiles) != 3 {
		t.Fatalf("record = %+v, want a 3-tile play", rec)
	}
	if blank := rec.Tiles[0]; blank.Letter != "c" || !blank.Blank {
		t.Errorf("blank tile = %+v, want letter \"c\" with Blank=true", blank)
	}
	if rec.Tiles[1].Blank || rec.Tiles[1].Letter != "a" {
		t.Errorf("second tile = %+v, want plain \"a\"", rec.Tiles[1])
	}
	if len(rec.Words) == 0 || rec.Words[0] != "cat" {
		t.Errorf("words = %v, want main word \"cat\"", rec.Words)
	}

	rs2, err := Ruleset(VariantEnglish)
	if err != nil {
		t.Fatalf("ruleset: %v", err)
	}
	b, err := ReplayBoard(rs2, []MoveRecord{rec})
	if err != nil {
		t.Fatalf("replay: %v", err)
	}
	if b.At(row, col)&blankCellFlag == 0 {
		t.Error("replayed centre cell lost its blank flag")
	}
	if !b.Filled(row, col+1) || b.At(row, col+1)&blankCellFlag != 0 {
		t.Error("replayed \"a\" cell should be a filled, non-blank tile")
	}
}
