package model

import (
	"strings"

	"github.com/tech/sendico/pkg/db/storable"
	"github.com/tech/sendico/pkg/mservice"
)

// OrchestrationStep defines a template step for execution planning.
type OrchestrationStep struct {
	StepID       string        `bson:"stepId" json:"stepId"`
	Rail         Rail          `bson:"rail" json:"rail"`
	Operation    string        `bson:"operation" json:"operation"`
	DependsOn    []string      `bson:"dependsOn,omitempty" json:"dependsOn,omitempty"`
	CommitPolicy CommitPolicy  `bson:"commitPolicy,omitempty" json:"commitPolicy,omitempty"`
	CommitAfter  []string      `bson:"commitAfter,omitempty" json:"commitAfter,omitempty"`
}

// PaymentPlanTemplate stores reusable orchestration templates.
type PaymentPlanTemplate struct {
	storable.Base `bson:",inline" json:",inline"`

	FromRail  Rail               `bson:"fromRail" json:"fromRail"`
	ToRail    Rail               `bson:"toRail" json:"toRail"`
	Network   string             `bson:"network,omitempty" json:"network,omitempty"`
	Steps     []OrchestrationStep `bson:"steps,omitempty" json:"steps,omitempty"`
	IsEnabled bool               `bson:"isEnabled" json:"isEnabled"`
}

// Collection implements storable.Storable.
func (*PaymentPlanTemplate) Collection() string {
	return mservice.PaymentPlanTemplates
}

// Normalize standardizes template fields for matching and indexing.
func (t *PaymentPlanTemplate) Normalize() {
	if t == nil {
		return
	}
	t.FromRail = Rail(strings.ToUpper(strings.TrimSpace(string(t.FromRail))))
	t.ToRail = Rail(strings.ToUpper(strings.TrimSpace(string(t.ToRail))))
	t.Network = strings.ToUpper(strings.TrimSpace(t.Network))
	if len(t.Steps) == 0 {
		return
	}
	for i := range t.Steps {
		step := &t.Steps[i]
		step.StepID = strings.TrimSpace(step.StepID)
		step.Rail = Rail(strings.ToUpper(strings.TrimSpace(string(step.Rail))))
		step.Operation = strings.ToLower(strings.TrimSpace(step.Operation))
		step.CommitPolicy = normalizeCommitPolicy(step.CommitPolicy)
		step.DependsOn = normalizeStringList(step.DependsOn)
		step.CommitAfter = normalizeStringList(step.CommitAfter)
	}
}

// PaymentPlanTemplateFilter selects templates for lookup.
type PaymentPlanTemplateFilter struct {
	FromRail  Rail
	ToRail    Rail
	Network   string
	IsEnabled *bool
}

// PaymentPlanTemplateList holds template results.
type PaymentPlanTemplateList struct {
	Items []*PaymentPlanTemplate
}
