package bootstrapimpl

import (
	"fmt"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/nexuscrm/shared/pkg/constants"
)

// TestCollectEmailFieldColumns_ReturnsMapForEmailFields verifies that
// collectEmailFieldColumns returns active physical email columns and uses
// PhysicalName/ApiName fallback consistently with the other index collectors.
func TestCollectEmailFieldColumns_ReturnsMapForEmailFields(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	mock.ExpectQuery(objectQueryStr).WillReturnRows(sqlmock.NewRows([]string{
		constants.ColSysObject_ID,
		constants.ColSysObject_APIName,
		constants.FieldSysObject_ReadSource,
	}).AddRow("obj1", "Lead", nil))

	mock.ExpectQuery(fieldQueryStr).WillReturnRows(sqlmock.NewRows([]string{
		constants.ColSysField_ObjectID,
		"col",
	}).AddRow("obj1", "Email"))

	got, err := collectEmailFieldColumns(db)
	if err != nil {
		t.Fatalf("collectEmailFieldColumns() error = %v; want nil", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("unmet sqlmock expectations: %v", err)
	}

	cols, ok := got["Lead"]
	if !ok {
		t.Fatalf("collectEmailFieldColumns() missing table key %q; got %v", "Lead", got)
	}
	if !cols["Email"] {
		t.Fatalf("collectEmailFieldColumns()[Lead] missing col %q; got %v", "Email", cols)
	}
}

// TestCollectEmailFieldColumns_EmptyWhenNoEmailFields verifies the collector
// returns an empty map rather than an error when no email fields exist.
func TestCollectEmailFieldColumns_EmptyWhenNoEmailFields(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	mock.ExpectQuery(objectQueryStr).WillReturnRows(sqlmock.NewRows([]string{
		constants.ColSysObject_ID,
		constants.ColSysObject_APIName,
		constants.FieldSysObject_ReadSource,
	}))
	mock.ExpectQuery(fieldQueryStr).WillReturnRows(sqlmock.NewRows([]string{
		constants.ColSysField_ObjectID,
		"col",
	}))

	got, err := collectEmailFieldColumns(db)
	if err != nil {
		t.Fatalf("collectEmailFieldColumns() error = %v; want nil", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("unmet sqlmock expectations: %v", err)
	}
	if len(got) != 0 {
		t.Fatalf("collectEmailFieldColumns() = %v; want empty map", got)
	}
}

// TestCollectEmailFieldColumns_ObjectQueryError verifies query failures bubble
// up to the caller.
func TestCollectEmailFieldColumns_ObjectQueryError(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	mock.ExpectQuery(objectQueryStr).WillReturnError(fmt.Errorf("db error"))

	if _, err := collectEmailFieldColumns(db); err == nil {
		t.Fatal("collectEmailFieldColumns() expected error; got nil")
	}
}
