package dbstore

import (
	"fmt"

	"git.linuxforward.com/byop/byop-engine/dbmanager"
	"git.linuxforward.com/byop/byop-engine/models"
	"github.com/google/uuid"
	"gorm.io/gorm"
)

// ComponentStore handles database operations for components
type ComponentStore struct {
	db *gorm.DB
}

// NewComponentStore creates a new ComponentStore
func NewComponentStore(dbManager dbmanager.DbManager) *ComponentStore {
	return &ComponentStore{
		db: dbManager.GetDB(),
	}
}

// Create creates a new component
func (cs *ComponentStore) Create(component *models.Component) error {
	// Generate ID if not provided
	if component.ID == "" {
		component.ID = uuid.New().String()
	}

	// GORM will handle created_at and updated_at automatically
	return cs.db.Create(component).Error
}

// GetByID retrieves a component by ID
func (cs *ComponentStore) GetByID(id string) (*models.Component, error) {
	var component models.Component
	result := cs.db.First(&component, "id = ?", id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			return nil, nil // No component found
		}
		return nil, fmt.Errorf("failed to get component: %w", result.Error)
	}
	return &component, nil
}

// Update updates an existing component
func (cs *ComponentStore) Update(component *models.Component) error {
	return cs.db.Save(component).Error
}

// Delete deletes a component by ID
func (cs *ComponentStore) Delete(id string) error {
	return cs.db.Delete(&models.Component{}, "id = ?", id).Error
}

// List retrieves all components with optional filtering
func (cs *ComponentStore) List(filter map[string]interface{}) ([]*models.Component, error) {
	var components []*models.Component

	// Build query from filters
	query := cs.db
	if filter != nil {
		for key, value := range filter {
			query = query.Where(key+" = ?", value)
		}
	}

	// Execute query
	if err := query.Find(&components).Error; err != nil {
		return nil, fmt.Errorf("failed to list components: %w", err)
	}

	return components, nil
}

// GetComponentWithDeployments retrieves a component by ID with associated deployments
func (cs *ComponentStore) GetComponentWithDeployments(id string) (*models.Component, error) {
	var component models.Component
	result := cs.db.Preload("Deployments").First(&component, "id = ?", id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			return nil, nil // No component found
		}
		return nil, fmt.Errorf("failed to get component: %w", result.Error)
	}
	return &component, nil
}
