package db

import (
	"context"
	"database/sql"
	"embed"
	"fmt"

	"github.com/jackc/pgx/v5/pgxpool"
	_ "github.com/jackc/pgx/v5/stdlib" // pgx/v5 driver for database/sql
	"github.com/pressly/goose/v3"
)

// RunMigrations applies all pending goose migrations from the embedded FS.
// It uses the pgx/v5/stdlib bridge so that goose's database/sql interface
// can speak to the same Postgres as the rest of the application.
//
// Call RunMigrations once at startup, before constructing the router.
// goose.Up is idempotent — already-applied migrations are skipped.
func RunMigrations(ctx context.Context, pool *pgxpool.Pool, migrationsFS embed.FS) error {
	// Extract the DSN from the pool's connection config.
	connConfig := pool.Config().ConnConfig
	dsn := connConfig.ConnString()

	// Open a database/sql connection for goose. The pgx/v5 stdlib driver is
	// registered by the blank import above.
	sqlDB, err := sql.Open("pgx/v5", dsn)
	if err != nil {
		return fmt.Errorf("migrate: open sql.DB: %w", err)
	}
	sqlDB.SetMaxOpenConns(2) // goose runs sequentially — no need for a large pool
	defer sqlDB.Close()

	// Point goose at the embedded FS so no on-disk files are needed.
	goose.SetBaseFS(migrationsFS)
	if err := goose.SetDialect("postgres"); err != nil {
		return fmt.Errorf("migrate: set dialect: %w", err)
	}

	if err := goose.Up(sqlDB, "migrations"); err != nil {
		return fmt.Errorf("migrate: goose up: %w", err)
	}

	return nil
}
