package dbstore

import (
	"context"
	"fmt"

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

// CreateComponent creates a new component using GORM
func (s *SQLiteStore) CreateComponent(ctx context.Context, component *models.Component) error {
	result := s.db.WithContext(ctx).Create(component)
	if result.Error != nil {
		return fmt.Errorf("failed to create component: %w", result.Error)
	}
	return nil
}

// GetComponentsByUserID retrieves all components for a specific user using GORM
func (s *SQLiteStore) GetComponentsByUserID(ctx context.Context, userID uint) ([]*models.Component, error) {
	var components []*models.Component
	result := s.db.WithContext(ctx).Where("user_id = ?", userID).Find(&components)
	if result.Error != nil {
		return nil, fmt.Errorf("failed to get components by user ID: %w", result.Error)
	}
	return components, nil
}

// GetAllComponents retrieves all components using GORM
func (s *SQLiteStore) GetAllComponents(ctx context.Context) ([]*models.Component, error) {
	var components []*models.Component
	result := s.db.WithContext(ctx).Find(&components)
	if result.Error != nil {
		return nil, fmt.Errorf("failed to get all components: %w", result.Error)
	}
	return components, nil
}

// GetComponentByID retrieves a component by ID using GORM
func (s *SQLiteStore) GetComponentByID(ctx context.Context, id uint) (*models.Component, error) {
	var component models.Component
	result := s.db.WithContext(ctx).First(&component, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			return nil, models.NewErrNotFound(fmt.Sprintf("component with ID %d not found", id), result.Error)
		}
		return nil, fmt.Errorf("failed to get component by ID: %w", result.Error)
	}
	return &component, nil
}

// UpdateComponent updates an existing component using GORM
func (s *SQLiteStore) UpdateComponent(ctx context.Context, component *models.Component) error {
	result := s.db.WithContext(ctx).Save(component)
	if result.Error != nil {
		return fmt.Errorf("failed to update component: %w", result.Error)
	}
	if result.RowsAffected == 0 {
		return models.NewErrNotFound(fmt.Sprintf("component with ID %d not found for update", component.ID), nil)
	}
	return nil
}

// UpdateComponentStatus updates the status and error message of a component using GORM
func (s *SQLiteStore) UpdateComponentStatus(ctx context.Context, componentID uint, status string, errorMsg string) error {
	result := s.db.WithContext(ctx).Model(&models.Component{}).Where("id = ?", componentID).Updates(map[string]interface{}{
		"status":    status,
		"error_msg": errorMsg,
	})
	if result.Error != nil {
		return fmt.Errorf("failed to update component status: %w", result.Error)
	}
	if result.RowsAffected == 0 {
		return models.NewErrNotFound(fmt.Sprintf("component with ID %d not found for status update", componentID), nil)
	}
	return nil
}

// UpdateComponentImageInfo updates the image information of a component using GORM
func (s *SQLiteStore) UpdateComponentImageInfo(ctx context.Context, componentID uint, imageTag string, imageURI string) error {
	result := s.db.WithContext(ctx).Model(&models.Component{}).Where("id = ?", componentID).Updates(map[string]interface{}{
		"current_image_tag": imageTag,
		"current_image_uri": imageURI,
	})
	if result.Error != nil {
		return fmt.Errorf("failed to update component image info: %w", result.Error)
	}
	if result.RowsAffected == 0 {
		return models.NewErrNotFound(fmt.Sprintf("component with ID %d not found for image info update", componentID), nil)
	}
	return nil
}

// DeleteComponent deletes a component by ID using GORM
func (s *SQLiteStore) DeleteComponent(ctx context.Context, id uint) error {
	result := s.db.WithContext(ctx).Delete(&models.Component{}, id)
	if result.Error != nil {
		return fmt.Errorf("failed to delete component: %w", result.Error)
	}
	if result.RowsAffected == 0 {
		return models.NewErrNotFound(fmt.Sprintf("component with ID %d not found for deletion", id), nil)
	}
	return nil
}
