package services

import (
	"fmt"

	"git.linuxforward.com/byop/byop-engine/dbstore"
	"git.linuxforward.com/byop/byop-engine/models"
	"github.com/google/uuid"
)

// ComponentService handles business logic for components
type ComponentService struct {
	store *dbstore.ComponentStore
}

// NewComponentService creates a new ComponentService
func NewComponentService(store *dbstore.ComponentStore) *ComponentService {
	return &ComponentService{store: store}
}

// CreateComponent creates a new component
func (s *ComponentService) CreateComponent(component *models.Component) error {
	// Generate UUID if not provided
	if component.ID == "" {
		component.ID = uuid.New().String()
	}

	// Set default resource values if not provided
	if component.Resources.CPU == "" {
		component.Resources.CPU = "0.5"
	}
	if component.Resources.Memory == "" {
		component.Resources.Memory = "512Mi"
	}
	if component.Resources.Storage == "" {
		component.Resources.Storage = "1Gi"
	}

	// Set default scale settings if not provided
	if component.ScaleSettings.MinInstances == 0 {
		component.ScaleSettings.MinInstances = 1
	}
	if component.ScaleSettings.MaxInstances == 0 {
		component.ScaleSettings.MaxInstances = 3
	}
	if component.ScaleSettings.CPUThreshold == 0 {
		component.ScaleSettings.CPUThreshold = 80
	}

	// Persist the component
	return s.store.Create(component)
}

// GetComponent retrieves a component by ID
func (s *ComponentService) GetComponent(id string) (*models.Component, error) {
	component, err := s.store.GetByID(id)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve component: %w", err)
	}
	return component, nil
}

// UpdateComponent updates an existing component
func (s *ComponentService) UpdateComponent(component *models.Component) error {
	if component.ID == "" {
		return fmt.Errorf("component ID is required for update")
	}

	// Check if component exists
	existingComponent, err := s.store.GetByID(component.ID)
	if err != nil {
		return fmt.Errorf("failed to check if component exists: %w", err)
	}
	if existingComponent == nil {
		return fmt.Errorf("component with ID %s not found", component.ID)
	}

	return s.store.Update(component)
}

// DeleteComponent deletes a component by ID
func (s *ComponentService) DeleteComponent(id string) error {
	// Check if component exists
	component, err := s.store.GetByID(id)
	if err != nil {
		return fmt.Errorf("failed to check if component exists: %w", err)
	}
	if component == nil {
		return fmt.Errorf("component with ID %s not found", id)
	}

	return s.store.Delete(id)
}

// ListComponents retrieves all components with optional filtering
func (s *ComponentService) ListComponents(filter map[string]interface{}) ([]*models.Component, error) {
	return s.store.List(filter)
}

// GetComponentDeployments retrieves all deployments for a component
func (s *ComponentService) GetComponentDeployments(id string) ([]models.DeployedComponent, error) {
	// First check if the component exists
	component, err := s.store.GetByID(id)
	if err != nil {
		return nil, fmt.Errorf("failed to check if component exists: %w", err)
	}
	if component == nil {
		return nil, fmt.Errorf("component with ID %s not found", id)
	}

	// Get component with deployments
	componentWithDeployments, err := s.store.GetComponentWithDeployments(id)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve component deployments: %w", err)
	}

	return componentWithDeployments.Deployments, nil
}
