package services

import (
	"os"
	"path/filepath"
	"time"

	"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/db"
	"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/models"
	"gitea.hostxtra.co.uk/mrhid6/vantage/shared/provision"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/v2/bson"
	"go.mongodb.org/mongo-driver/v2/mongo/options"
)

func DefaultStepsDir() string {
	dir := os.Getenv("VANTAGE_DEFAULT_STEPS_DIR")
	if dir == "" {
		dir = filepath.Join("data", "default-steps")
	}
	_ = os.MkdirAll(dir, 0700)
	return dir
}

func readDefaultStepFiles() ([]models.WorkflowStep, error) {
	matches, err := filepath.Glob(filepath.Join(DefaultStepsDir(), "*.json"))
	if err != nil {
		return nil, err
	}
	out := []models.WorkflowStep{}
	for _, path := range matches {
		b, err := os.ReadFile(path)
		if err != nil {
			continue
		}
		s, err := ParseStepDoc(b)
		if err != nil {
			continue
		}
		s.Source = "default"
		s.Slug = provision.Slugify(s.Name)
		if s.Slug == "" {
			continue
		}
		out = append(out, s)
	}
	return out, nil
}

func SeedDefaultSteps(instanceID string) (created, updated int, err error) {
	steps, err := readDefaultStepFiles()
	if err != nil {
		return 0, 0, err
	}
	ctx, cancel := wfCtx()
	defer cancel()
	col := db.Col("workflow_steps")
	for _, s := range steps {
		filter := bson.M{"instance_id": instanceID, "slug": s.Slug, "source": "default"}
		set := bson.M{
			"name":             s.Name,
			"description":      s.Description,
			"interpreter":      s.Interpreter,
			"script":           s.Script,
			"declared_outputs": s.DeclaredOutputs,
			"declared_inputs":  s.DeclaredInputs,
			"secret_refs":      s.SecretRefs,
			"updated_at":       time.Now(),
		}
		res, uerr := col.UpdateOne(ctx, filter, bson.M{
			"$set": set,
			"$setOnInsert": bson.M{
				"instance_id": instanceID,
				"step_id":     uuid.New().String(),
				"slug":        s.Slug,
				"source":      "default",
				"created_at":  time.Now(),
			},
		}, options.UpdateOne().SetUpsert(true))
		if uerr != nil {
			return created, updated, uerr
		}
		if res.UpsertedCount > 0 {
			created++
		} else if res.ModifiedCount > 0 {
			updated++
		}
	}
	return created, updated, nil
}
