package shared

import (
	"fmt"
	"strings"

	"gitea.maximumdirect.net/eric/notarius/internal/core/source"
)

// CitationResolver resolves cited ranges against one source document.
type CitationResolver struct {
	doc   *source.SourceDocument
	index source.DocumentIndex
}

// NewCitationResolver prepares citation resolution for doc.
func NewCitationResolver(doc *source.SourceDocument) (*CitationResolver, error) {
	if doc == nil {
		return nil, fmt.Errorf("source document must not be nil")
	}
	return &CitationResolver{doc: doc, index: source.NewDocumentIndex(doc)}, nil
}

// CitedText resolves cited source ranges in document order, including each
// source unit once, and joins the resulting text with newlines.
func (r *CitationResolver) CitedText(refs []source.SourceRef) (string, error) {
	included := make([]bool, len(r.doc.Units))
	for _, ref := range refs {
		if err := r.index.ValidateRef(ref); err != nil {
			return "", fmt.Errorf("resolve cited source range: %w", err)
		}
		start, _ := r.index.Position(ref.StartUnitID)
		end, _ := r.index.Position(ref.EndUnitID)
		for index := start; index <= end; index++ {
			included[index] = true
		}
	}

	parts := make([]string, 0, len(r.doc.Units))
	for index, unit := range r.doc.Units {
		if included[index] {
			parts = append(parts, unit.Text)
		}
	}
	return strings.Join(parts, "\n"), nil
}
