package database

import (
	"fmt"
	"time"

	"context"

	"github.com/jackc/pgx/v5/pgxpool"
)

// DB wraps the pgx pool
type DB struct {
	Pool *pgxpool.Pool
}

// Connect establishes a connection to the PostgreSQL database
func Connect(databaseURL string) (*DB, error) {
	config, err := pgxpool.ParseConfig(databaseURL)
	if err != nil {
		return nil, fmt.Errorf("failed to parse database URL: %w", err)
	}

	// Configure connection pool
	config.MaxConns = 25
	config.MinConns = 5
	config.MaxConnLifetime = time.Hour
	config.MaxConnIdleTime = 30 * time.Minute
	config.HealthCheckPeriod = time.Minute

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	pool, err := pgxpool.NewWithConfig(ctx, config)
	if err != nil {
		return nil, fmt.Errorf("failed to create connection pool: %w", err)
	}

	// Test the connection
	if err := pool.Ping(ctx); err != nil {
		return nil, fmt.Errorf("failed to ping database: %w", err)
	}

	return &DB{Pool: pool}, nil
}

// Close closes the database connection pool
func (db *DB) Close() {
	db.Pool.Close()
}

// Migrate runs all database migrations in order.
func Migrate(db *DB) error {
	if err := migrateCore(db); err != nil {
		return err
	}
	if err := migrateOAuth(db); err != nil {
		return err
	}
	if err := migrateEmail(db); err != nil {
		return err
	}
	if err := migrateSchool(db); err != nil {
		return err
	}
	if err := migrateDSR(db); err != nil {
		return err
	}
	return nil
}
