package services

import (
	"fmt"

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

// AppService handles business logic for applications
type AppService struct {
	store *dbstore.AppStore
}

// NewAppService creates a new AppService
func NewAppService(store *dbstore.AppStore) *AppService {
	return &AppService{store: store}
}

// CreateApp creates a new application
func (s *AppService) CreateApp(app *models.App) error {
	// Generate UUID if not provided
	if app.ID == "" {
		app.ID = uuid.New().String()
	}

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

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

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

// GetApp retrieves an application by ID
func (s *AppService) GetApp(id string) (*models.App, error) {
	app, err := s.store.GetByID(id)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve app: %w", err)
	}
	return app, nil
}

// UpdateApp updates an existing application
func (s *AppService) UpdateApp(app *models.App) error {
	if app.ID == "" {
		return fmt.Errorf("app ID is required for update")
	}

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

	return s.store.Update(app)
}

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

	return s.store.Delete(id)
}

// ListApps retrieves all applications with optional filtering
func (s *AppService) ListApps(filter map[string]interface{}) ([]*models.App, error) {
	return s.store.List(filter)
}

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

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

	return appWithDeployments.Deployments, nil
}
