// Package mock provides mock implementations for testing
package mock

import (
	"context"
	"sync"

	"github.com/pfeifferj/container-mom-go/pkg/operator/mongodb/api"
	"github.com/stretchr/testify/mock"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// MockMongoDB is a mock implementation of the MongoDB interface
type MockMongoDB struct {
	mock.Mock
	deployments map[string]*api.MongoDeployment
	mu          sync.RWMutex
}

// NewMockMongoDB creates a new mock MongoDB client
func NewMockMongoDB() *MockMongoDB {
	return &MockMongoDB{}
}

// GetDeployment implements the MongoDB interface
func (m *MockMongoDB) GetDeployment(ctx context.Context, id string) (*api.MongoDeployment, error) {
	args := m.Called(ctx, id)
	if args.Get(0) == nil {
		return nil, args.Error(1)
	}
	return args.Get(0).(*api.MongoDeployment), args.Error(1)
}

// ListDeployments implements the MongoDB interface
func (m *MockMongoDB) ListDeployments(ctx context.Context) ([]api.MongoDeployment, error) {
	args := m.Called(ctx)
	return args.Get(0).([]api.MongoDeployment), args.Error(1)
}

// CreateDeployment implements the MongoDB interface
func (m *MockMongoDB) CreateDeployment(ctx context.Context, deployment *api.MongoDeployment) error {
	args := m.Called(ctx, deployment)
	return args.Error(0)
}

// UpdateDeployment implements the MongoDB interface
func (m *MockMongoDB) UpdateDeployment(ctx context.Context, deployment *api.MongoDeployment) error {
	args := m.Called(ctx, deployment)
	return args.Error(0)
}

// DeleteDeployment implements the MongoDB interface
func (m *MockMongoDB) DeleteDeployment(ctx context.Context, id string) error {
	args := m.Called(ctx, id)
	return args.Error(0)
}

// Ping implements a mock ping
func (m *MockMongoDB) Ping(_ context.Context, _ interface{}) error {
	return nil
}

// GetClient returns nil for the mock
func (m *MockMongoDB) GetClient() *mongo.Client {
	// Create a mock client using Connect instead of deprecated NewClient
	client, _ := mongo.Connect(context.Background(), options.Client())
	return client
}

func (m *MockMongoDB) Disconnect(_ context.Context) error {
	return nil // Nothing to disconnect in mock
}

func (m *MockMongoDB) Database(name string) *mongo.Database {
	// Return a mock database
	client := m.GetClient()
	return client.Database(name)
}

func (m *MockMongoDB) DeleteAllDeployments(_ context.Context) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.deployments = make(map[string]*api.MongoDeployment)
	return nil
}
