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"
)

// TemplateStore handles database operations for deployment templates
type TemplateStore struct {
	db *gorm.DB
}

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

// Create creates a new template
func (ts *TemplateStore) Create(template *models.Template) error {
	// Generate ID if not provided
	if template.ID == "" {
		template.ID = uuid.New().String()
	}

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

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

// Update updates an existing template
func (ts *TemplateStore) Update(template *models.Template) error {
	return ts.db.Save(template).Error
}

// Delete deletes a template by ID
func (ts *TemplateStore) Delete(id string) error {
	return ts.db.Delete(&models.Template{}, "id = ?", id).Error
}

// List retrieves all templates with optional filtering
func (ts *TemplateStore) List(filter map[string]interface{}) ([]*models.Template, error) {
	var templates []*models.Template

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

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

	return templates, nil
}

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

// GetByVersion retrieves a template by name and version
func (ts *TemplateStore) GetByVersion(name string, version string) (*models.Template, error) {
	var template models.Template
	result := ts.db.Where("name = ? AND version = ?", name, version).First(&template)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			return nil, nil // No template found
		}
		return nil, fmt.Errorf("failed to get template: %w", result.Error)
	}
	return &template, nil
}
