package docforge

import "context"

// TemplateMeta is the listable metadata for a stored template — cheap to
// list because it carries no carrier bytes.
type TemplateMeta struct {
	ID           string
	Slug         string // optional human handle; may be empty
	NameDE       string
	NameEN       string
	Kind         string // consumer-domain tag, e.g. "submission"
	SourceFormat string // "docx"
	Firm         string // may be empty
	IsActive     bool
	Version      int    // current version number; 0 when no version exists yet
	VersionID    string // current version row id; "" when no version exists yet.
	// A draft pins VersionID to snapshot this exact version (PRD §4 A3):
	// a later template edit creates a new version and re-points current,
	// but the pinned draft keeps rendering VersionID.
}

// TemplateSlot is one variable slot placed in a template version's carrier.
type TemplateSlot struct {
	// Key is the variable bound here, in the placeholder grammar
	// (e.g. "project.case_number").
	Key string
	// Anchor locates the slot within the carrier. With the sentinel
	// strategy this is the token the authoring surface injected into the
	// carrier OOXML at the slot position.
	Anchor string
	// Label is an optional human label for the authoring palette.
	Label string
	// OrderIndex orders slots for display.
	OrderIndex int
}

// Template is a stored template resolved to its current version: metadata
// plus everything needed to author or generate — the carrier bytes, the
// stylemap, and the placed slots. CarrierBytes is format-opaque; the .docx
// adapter wraps (CarrierBytes, Stylemap) into a docx.Carrier at compose
// time, so this root type never imports the adapter.
type Template struct {
	TemplateMeta
	CarrierBytes []byte
	Stylemap     map[string]string
	Slots        []TemplateSlot
}

// TemplateMetaInput is the payload for creating a new template (the
// catalog row). ID and Version are assigned by the store.
type TemplateMetaInput struct {
	Slug         string // optional
	NameDE       string
	NameEN       string
	Kind         string // defaults to "submission" when empty
	SourceFormat string // defaults to "docx" when empty
	Firm         string // optional
	CreatedBy    string // auth user id (uuid) for the audit column
}

// TemplateVersionInput is the payload for creating a template version: the
// carrier .docx, its stylemap, and the slots placed in it.
type TemplateVersionInput struct {
	CarrierBytes []byte
	Stylemap     map[string]string
	Slots        []TemplateSlot
	CreatedBy    string // auth user id (uuid)
}

// TemplateFilter narrows a List. Zero-value fields mean "any".
type TemplateFilter struct {
	Firm       string // "" = any firm
	Kind       string // "" = any kind
	ActiveOnly bool   // true = is_active templates only
}

// TemplateStore persists and loads document templates. docforge defines
// the contract; the consuming application implements it (paliad against
// Postgres, with the carrier bytes in a bytea column). It is the seam the
// authoring surface writes to and the generator reads from — a second
// docforge consumer implements the same interface against its own storage.
//
// Versioning is snapshot-at-create (PRD §4 A3): Create makes version 1 and
// pins it as current; AddVersion inserts the next version and re-points
// current. Drafts pin a specific version so a later edit never shifts an
// in-flight draft.
type TemplateStore interface {
	// List returns catalog metadata for templates matching the filter,
	// without carrier bytes.
	List(ctx context.Context, f TemplateFilter) ([]TemplateMeta, error)

	// Get returns a template resolved to its current version (carrier +
	// stylemap + slots). Returns ErrTemplateNotFound when id is unknown.
	Get(ctx context.Context, id string) (*Template, error)

	// GetVersion returns a template resolved to a specific version id —
	// the path a draft uses to render its pinned snapshot. Returns
	// ErrTemplateNotFound when the version is unknown.
	GetVersion(ctx context.Context, versionID string) (*Template, error)

	// Create inserts a new template plus its first version (version 1) and
	// pins that version as current. Returns the resolved Template.
	Create(ctx context.Context, meta TemplateMetaInput, first TemplateVersionInput) (*Template, error)

	// AddVersion inserts the next version for an existing template and
	// re-points current_version to it. Returns the resolved Template at
	// the new version. Returns ErrTemplateNotFound when templateID is
	// unknown.
	AddVersion(ctx context.Context, templateID string, v TemplateVersionInput) (*Template, error)
}
