package crud

import (
	"database/sql"
	"fmt"
	"sync"

	"aijianzhan/platform/internal/meta"
	"aijianzhan/platform/internal/schema"
)

// DBPool 按 database_per_app 缓存连接。
type DBPool struct {
	mu      sync.Mutex
	baseDSN string
	primary *sql.DB
	dbs     map[string]*sql.DB
}

func NewDBPool(defaultDB *sql.DB, baseDSN string) *DBPool {
	return &DBPool{primary: defaultDB, baseDSN: baseDSN, dbs: map[string]*sql.DB{}}
}

func (p *DBPool) ForApp(app *meta.AppRecord) (*sql.DB, error) {
	if p == nil {
		return nil, fmt.Errorf("db pool nil")
	}
	if app == nil || app.DatabaseName == "" {
		return p.primary, nil
	}
	p.mu.Lock()
	defer p.mu.Unlock()
	if db, ok := p.dbs[app.DatabaseName]; ok {
		return db, nil
	}
	dsn, err := schema.DSNForDatabase(p.baseDSN, app.DatabaseName)
	if err != nil {
		return nil, err
	}
	db, err := sql.Open("postgres", dsn)
	if err != nil {
		return nil, err
	}
	if err := db.Ping(); err != nil {
		_ = db.Close()
		return nil, fmt.Errorf("ping app db %s: %w", app.DatabaseName, err)
	}
	p.dbs[app.DatabaseName] = db
	return db, nil
}
