package parser

import (
	"strings"
	"testing"
)

func TestSaasDeepDocService_GroupCells(t *testing.T) {
	b := &SaasDeepDocService{}

	t.Run("labels group into rows", func(t *testing.T) {
		cells := []TSRCell{
			{X0: 0, Y0: 0, X1: 100, Y1: 30, Text: "H1", Label: "table column header"},
			{X0: 100, Y0: 0, X1: 200, Y1: 30, Text: "H2", Label: "table column header"},
			{X0: 0, Y0: 35, X1: 100, Y1: 65, Text: "A1", Label: "table row"},
			{X0: 100, Y0: 35, X1: 200, Y1: 65, Text: "B1", Label: "table row"},
			{X0: 0, Y0: 70, X1: 100, Y1: 100, Text: "A2", Label: "table row"},
			{X0: 100, Y0: 70, X1: 200, Y1: 100, Text: "B2", Label: "table row"},
		}
		grid := b.GroupCells(cells)
		if len(grid) != 3 {
			t.Fatalf("expected 3 rows, got %d", len(grid))
		}
		if len(grid[0]) != 2 || len(grid[1]) != 2 || len(grid[2]) != 2 {
			t.Errorf("expected 2 cols per row, got %d/%d/%d",
				len(grid[0]), len(grid[1]), len(grid[2]))
		}
	})

	t.Run("spanning cell added to row", func(t *testing.T) {
		cells := []TSRCell{
			{X0: 0, Y0: 0, X1: 200, Y1: 30, Text: "H1", Label: "table column header"},
			{X0: 100, Y0: 0, X1: 200, Y1: 30, Text: "H2", Label: "table column header"},
			{X0: 0, Y0: 0, X1: 200, Y1: 30, Text: "Span", Label: "table spanning cell"},
			{X0: 0, Y0: 35, X1: 100, Y1: 65, Text: "D1", Label: "table row"},
			{X0: 100, Y0: 35, X1: 200, Y1: 65, Text: "D2", Label: "table row"},
		}
		grid := b.GroupCells(cells)
		if len(grid) != 2 {
			t.Fatalf("expected 2 rows (header + data), got %d", len(grid))
		}
		if len(grid[0]) < 3 {
			t.Errorf("expected row 0 to contain 2 headers + spanning = 3 cells, got %d", len(grid[0]))
		}
	})

	t.Run("fallback to Y-proximity when no labels match", func(t *testing.T) {
		cells := []TSRCell{
			{X0: 0, Y0: 0, X1: 100, Y1: 30, Text: "C1", Label: "unknown"},
			{X0: 100, Y0: 0, X1: 200, Y1: 30, Text: "C2", Label: "unknown"},
			{X0: 0, Y0: 50, X1: 100, Y1: 80, Text: "D1", Label: "unknown"},
			{X0: 100, Y0: 50, X1: 200, Y1: 80, Text: "D2", Label: "unknown"},
		}
		grid := b.GroupCells(cells)
		if len(grid) != 2 {
			t.Fatalf("expected 2 rows from Y-proximity fallback, got %d", len(grid))
		}
		if len(grid[0]) != 2 || len(grid[1]) != 2 {
			t.Errorf("expected 2 cols per row, got %d/%d", len(grid[0]), len(grid[1]))
		}
	})
}

func TestSaasDeepDocService_Name(t *testing.T) {
	b := &SaasDeepDocService{}
	if b.Name() != "deepdoc" {
		t.Errorf("expected 'deepdoc', got %q", b.Name())
	}
}

func TestGatherTSR(t *testing.T) {
	cells := []TSRCell{
		{Label: "table row", Text: "A"},
		{Label: "table column header", Text: "H"},
		{Label: "table row", Text: "B"},
	}
	result := gatherTSR(cells, reRowHdr)
	if len(result) < 2 {
		t.Errorf("expected at least 2 matching cells, got %d", len(result))
	}
	for _, c := range result {
		if !strings.Contains("ABH", c.Text[:1]) {
			t.Errorf("unexpected cell in result: %+v", c)
		}
	}
}

func TestGroupTSRCellsToRowsLabeled_NoZeroHeightPhantomCells(t *testing.T) {
	// Row0: 1 row cell + 1 spanning cell → 2 cells.
	// Row1: 1 row cell → 1 cell.  maxCols=2 → Row1 padded.
	// The padded cell must have valid height from the real cell.
	cells := []TSRCell{
		{Label: "table row", X0: 0, Y0: 0, X1: 100, Y1: 20},
		{Label: "table spanning cell", X0: 120, Y0: 0, X1: 200, Y1: 20},
		{Label: "table row", X0: 0, Y0: 100, X1: 100, Y1: 120},
	}
	result := groupTSRCellsToRowsLabeled(cells)
	if len(result) != 2 {
		t.Fatalf("expected 2 rows, got %d", len(result))
	}
	if len(result[0]) != 2 {
		t.Fatalf("row 0: expected 2 cells, got %d", len(result[0]))
	}
	if len(result[1]) != 2 {
		t.Fatalf("row 1: expected 2 cells (padded), got %d", len(result[1]))
	}
	phantom := result[1][1]
	if phantom.Y1 <= phantom.Y0 {
		t.Errorf("phantom cell has zero height: Y0=%v Y1=%v", phantom.Y0, phantom.Y1)
	}
}
