package database

import (
	"database/sql"
	"fmt"
	"time"

	_ "github.com/lib/pq"
	"go.uber.org/zap"
)

type PostgresProvider struct {
	db     *sql.DB
	logger *zap.Logger
}

func NewPostgresProvider(dsn string, maxOpenConns, maxIdleConns int, connMaxLifetime string, logger *zap.Logger) (*sql.DB, error) {
	db, err := sql.Open("postgres", dsn)
	if err != nil {
		return nil, fmt.Errorf("failed to open database connection: %w", err)
	}

	// Configure connection pool
	db.SetMaxOpenConns(maxOpenConns)
	db.SetMaxIdleConns(maxIdleConns)

	if connMaxLifetime != "" {
		lifetime, err := time.ParseDuration(connMaxLifetime)
		if err != nil {
			return nil, fmt.Errorf("invalid connection max lifetime: %w", err)
		}
		db.SetConnMaxLifetime(lifetime)
	}

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

	return db, nil
}

func (p *PostgresProvider) Close() error {
	if p.db != nil {
		return p.db.Close()
	}
	return nil
}

func (p *PostgresProvider) Ping() error {
	if p.db != nil {
		return p.db.Ping()
	}
	return fmt.Errorf("database connection is nil")
}

func (p *PostgresProvider) GetDB() *sql.DB {
	return p.db
}