package db

import (
	"context"

	mongoimpl "github.com/tech/sendico/pkg/db/internal/mongo"
	"github.com/tech/sendico/pkg/merrors"
	"github.com/tech/sendico/pkg/mlogger"
	"go.mongodb.org/mongo-driver/v2/mongo"
	"go.mongodb.org/mongo-driver/v2/mongo/readpref"
)

// Connection represents a low-level database connection lifecycle.
type Connection interface {
	Disconnect(ctx context.Context) error
	Ping(ctx context.Context) error
}

// MongoConnection provides direct access to the underlying mongo client.
type MongoConnection struct {
	client   *mongo.Client
	database string
}

func (c *MongoConnection) Client() *mongo.Client {
	return c.client
}

func (c *MongoConnection) Database() *mongo.Database {
	return c.client.Database(c.database)
}

func (c *MongoConnection) Disconnect(ctx context.Context) error {
	return c.client.Disconnect(ctx)
}

func (c *MongoConnection) Ping(ctx context.Context) error {
	return c.client.Ping(ctx, readpref.Primary())
}

// ConnectMongo returns a low-level MongoDB connection without constructing repositories.
func ConnectMongo(logger mlogger.Logger, config *Config) (*MongoConnection, error) {
	if config == nil {
		return nil, merrors.InvalidArgument("database configuration is nil", "config")
	}
	if config.Driver != Mongo {
		return nil, merrors.InvalidArgument("unsupported database driver: "+string(config.Driver), "config.driver")
	}

	client, _, settings, err := mongoimpl.ConnectClient(logger, config.Settings)
	if err != nil {
		return nil, err
	}

	return &MongoConnection{
		client:   client,
		database: settings.Database,
	}, nil
}
