package core

import (
	"database/sql"
	"fmt"
	"sort"
	"strings"
	"testing"
)

// TestDBSeed inserta dinamicamente filas en una tabla usando una transaccion.
// Cada fila se representa como map[string]any. Las columnas se infieren del
// primer mapa y se mantienen en orden alfabetico para consistencia.
// Llama t.Fatal si la transaccion falla.
func TestDBSeed(t *testing.T, db *sql.DB, table string, rows []map[string]any) error {
	t.Helper()

	if len(rows) == 0 {
		return nil
	}

	// Inferir columnas del primer mapa (orden alfabetico para reproducibilidad)
	cols := make([]string, 0, len(rows[0]))
	for col := range rows[0] {
		cols = append(cols, col)
	}
	sort.Strings(cols)

	placeholders := make([]string, len(cols))
	for i := range placeholders {
		placeholders[i] = "?"
	}

	query := fmt.Sprintf(
		"INSERT INTO %s (%s) VALUES (%s)",
		table,
		strings.Join(cols, ", "),
		strings.Join(placeholders, ", "),
	)

	tx, err := db.Begin()
	if err != nil {
		return fmt.Errorf("TestDBSeed: begin tx: %w", err)
	}

	stmt, err := tx.Prepare(query)
	if err != nil {
		tx.Rollback()
		return fmt.Errorf("TestDBSeed: prepare: %w", err)
	}
	defer stmt.Close()

	for _, row := range rows {
		args := make([]any, len(cols))
		for i, col := range cols {
			args[i] = row[col]
		}
		if _, err := stmt.Exec(args...); err != nil {
			tx.Rollback()
			return fmt.Errorf("TestDBSeed: exec row: %w", err)
		}
	}

	if err := tx.Commit(); err != nil {
		return fmt.Errorf("TestDBSeed: commit: %w", err)
	}

	return nil
}
