package dbmanager

import (
	"fmt"

	"git.linuxforward.com/byop/byop-engine/models"
)

// MemoryDbManager implements DbManager using in-memory storage
type MemoryDbManager struct {
	// In-memory database storage

	// User storage
	users map[string]*models.User

	// Client storage
	clients map[string]*models.Client
	// Deployment storage
	deployments map[string]*models.Deployment
	// Other entity storage
	// ...
}

// NewMemoryDbManager creates a new MemoryDbManager
func NewMemoryDbManager() *MemoryDbManager {
	return &MemoryDbManager{
		users:       make(map[string]*models.User),
		clients:     make(map[string]*models.Client),
		deployments: make(map[string]*models.Deployment),
	}
}

// Connect establishes a connection to the in-memory database
func (m *MemoryDbManager) Connect() error {
	// No action needed for in-memory storage
	return nil
}

// Disconnect closes the connection to the in-memory database
func (m *MemoryDbManager) Disconnect() error {
	// No action needed for in-memory storage
	return nil
}

// Exec executes a query against the in-memory database
func (m *MemoryDbManager) Exec(query string, args ...interface{}) (interface{}, error) {
	// In-memory storage does not support complex queries
	// Implement simple query execution if needed
	return nil, fmt.Errorf("exec not supported in in-memory storage")
}

// Create creates a new entity in the in-memory database
func (m *MemoryDbManager) Create(entityType string, entity interface{}) error {
	switch entityType {
	case "users":
		user, ok := entity.(*models.User)
		if !ok {
			return fmt.Errorf("invalid user type")
		}
		m.users[user.ID] = user
	case "clients":
		client, ok := entity.(*models.Client)
		if !ok {
			return fmt.Errorf("invalid client type")
		}
		m.clients[client.ID] = client
	case "deployments":
		deployment, ok := entity.(*models.Deployment)
		if !ok {
			return fmt.Errorf("invalid deployment type")
		}
		m.deployments[deployment.ID] = deployment
	default:
		return fmt.Errorf("unsupported entity type: %s", entityType)
	}
	return nil
}

// GetByID retrieves an entity by ID from the in-memory database
func (m *MemoryDbManager) GetByID(entityType string, id string) (interface{}, error) {
	switch entityType {
	case "users":
		user, exists := m.users[id]
		if !exists {
			return nil, fmt.Errorf("user not found")
		}
		return user, nil
	case "clients":
		client, exists := m.clients[id]
		if !exists {
			return nil, fmt.Errorf("client not found")
		}
		return client, nil
	case "deployments":
		deployment, exists := m.deployments[id]
		if !exists {
			return nil, fmt.Errorf("deployment not found")
		}
		return deployment, nil
	default:
		return nil, fmt.Errorf("unsupported entity type: %s", entityType)
	}
}

// Update updates an existing entity in the in-memory database
func (m *MemoryDbManager) Update(entityType string, entity interface{}) error {
	switch entityType {
	case "users":
		user, ok := entity.(*models.User)
		if !ok {
			return fmt.Errorf("invalid user type")
		}
		m.users[user.ID] = user
	case "clients":
		client, ok := entity.(*models.Client)
		if !ok {
			return fmt.Errorf("invalid client type")
		}
		m.clients[client.ID] = client
	case "deployments":
		deployment, ok := entity.(*models.Deployment)
		if !ok {
			return fmt.Errorf("invalid deployment type")
		}
		m.deployments[deployment.ID] = deployment
	default:
		return fmt.Errorf("unsupported entity type: %s", entityType)
	}
	return nil
}

// Delete deletes an entity by ID from the in-memory database
func (m *MemoryDbManager) Delete(entityType string, id string) error {
	switch entityType {
	case "users":
		delete(m.users, id)
	case "clients":
		delete(m.clients, id)
	case "deployments":
		delete(m.deployments, id)
	default:
		return fmt.Errorf("unsupported entity type: %s", entityType)
	}
	return nil
}

// ListByFilter retrieves entities based on a filter from the in-memory database
func (m *MemoryDbManager) List(entityType string, filter map[string]interface{}) ([]interface{}, error) {
	switch entityType {
	case "users":
		users := make([]interface{}, 0, len(m.users))
		for _, user := range m.users {
			if matchesFilter(user, filter) {
				users = append(users, user)
			}
		}
		return users, nil
	case "clients":
		clients := make([]interface{}, 0, len(m.clients))
		for _, client := range m.clients {
			if matchesFilter(client, filter) {
				clients = append(clients, client)
			}
		}
		return clients, nil
	case "deployments":
		deployments := make([]interface{}, 0, len(m.deployments))
		for _, deployment := range m.deployments {
			if matchesFilter(deployment, filter) {
				deployments = append(deployments, deployment)
			}
		}
		return deployments, nil
	default:
		return nil, fmt.Errorf("unsupported entity type: %s", entityType)
	}
}

// matchesFilter checks if an entity matches the given filter
func matchesFilter(entity interface{}, filter map[string]interface{}) bool {
	// Implement your filtering logic here
	// For example, check if the entity's fields match the filter criteria
	return true // Placeholder, implement actual filtering logic
}
