package dbstore

import (
	"context"
	"fmt"

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

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

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

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

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

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

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

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

// GetDeploymentsByUserID retrieves all deployments for a specific user via their apps using GORM
func (s *SQLiteStore) GetDeploymentsByUserID(ctx context.Context, userID uint) ([]*models.Deployment, error) {
	var deployments []*models.Deployment
	result := s.db.WithContext(ctx).
		Joins("JOIN apps ON deployments.app_id = apps.id").
		Where("apps.user_id = ?", userID).
		Find(&deployments)
	if result.Error != nil {
		return nil, fmt.Errorf("failed to get deployments by user ID: %w", result.Error)
	}
	return deployments, nil
}
