package bootstrapimpl

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/nexuscrm/automation/autonumber"
)

func TestQueryLivePerPrefixCountersStrictReportsLegacyDrift(t *testing.T) {
	t.Setenv(envTolerateLegacy, "")

	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	expectOrderNumberLiveScan(mock)

	var violations []string
	got, err := queryLivePerPrefixCounters(
		context.Background(),
		db,
		"Order",
		"OrderNumber",
		derivedOrderNumberRegex(t),
		"field-order-number",
		func(format string, args ...any) {
			violations = append(violations, fmt.Sprintf(format, args...))
		},
	)
	if err != nil {
		t.Fatalf("queryLivePerPrefixCounters: %v", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("sqlmock expectations: %v", err)
	}

	if got["US-OF-260629"] != 9 {
		t.Fatalf("matching row should still produce prefix max 9, got %#v", got)
	}
	if len(violations) != 1 {
		t.Fatalf("expected one strict-mode V7 violation, got %d: %#v", len(violations), violations)
	}
	if !strings.Contains(violations[0], `value "00005851" does not match derived regex`) {
		t.Fatalf("unexpected violation: %s", violations[0])
	}
}

func TestQueryLivePerPrefixCountersLegacyToleranceSkipsOnlyNonMatchingRows(t *testing.T) {
	t.Setenv(envTolerateLegacy, "true")

	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	expectOrderNumberLiveScan(mock)

	var violations []string
	got, err := queryLivePerPrefixCounters(
		context.Background(),
		db,
		"Order",
		"OrderNumber",
		derivedOrderNumberRegex(t),
		"field-order-number",
		func(format string, args ...any) {
			violations = append(violations, fmt.Sprintf(format, args...))
		},
	)
	if err != nil {
		t.Fatalf("queryLivePerPrefixCounters: %v", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("sqlmock expectations: %v", err)
	}

	if got["US-OF-260629"] != 9 {
		t.Fatalf("matching row should still produce prefix max 9, got %#v", got)
	}
	if len(violations) != 0 {
		t.Fatalf("expected legacy-tolerant V7 to skip only non-matching rows, got %#v", violations)
	}
}

func expectOrderNumberLiveScan(mock sqlmock.Sqlmock) {
	mock.ExpectQuery(regexp.QuoteMeta(
		"SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS "+
			"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",
	)).
		WithArgs("Order", "OrderNumber").
		WillReturnRows(sqlmock.NewRows([]string{"COUNT(*)"}).AddRow(1))

	mock.ExpectQuery(regexp.QuoteMeta(
		"SELECT `Id`, `OrderNumber` FROM `Order` " +
			"WHERE `OrderNumber` IS NOT NULL AND `OrderNumber` != ''",
	)).
		WillReturnRows(sqlmock.NewRows([]string{"Id", "OrderNumber"}).
			AddRow("legacy-order", "00005851").
			AddRow("new-order", "US-OF-26062909"))
}

func derivedOrderNumberRegex(t *testing.T) *regexp.Regexp {
	t.Helper()

	spec, _, err := autonumber.Parse("{Order.Account_Country_Code__c}-OF-{YY}{MM}{DD}{00}")
	if err != nil {
		t.Fatalf("parse format: %v", err)
	}
	derived, err := deriveCounterRegex(spec)
	if err != nil {
		t.Fatalf("derive regex: %v", err)
	}
	return derived
}
