package pipeline

import (
	"context"
	"fmt"
	"reflect"

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

type erasedExtractArtifact struct {
	LaneID, ExtractorKey, SourceID, ChunkID string
	ChunkIndex                              int
	ChunkRef                                source.SourceRef
	Value                                   any
}

type erasedMergeArtifact struct {
	LaneID, MergerKey, SourceID string
	Value                       any
}

type erasedTypedResult struct {
	Value          any
	Diagnostics    []contracts.ProducerDiagnostic
	Retry          *contracts.NormalizeRetry
	ModelCandidate *contracts.ModelCandidate
}

type typedValidationTarget struct {
	stage                          ModuleStage
	stepID                         string
	laneID                         string
	moduleKey                      string
	source                         *source.SourceDocument
	sourceID                       string
	sourceInput                    contracts.LLMInputMaterial
	sessionID                      string
	references                     contracts.ReferenceSet
	llmProfile                     string
	structuredOutputRepairAttempts *int
	metadata                       map[string]any
	chunk                          *source.Chunk
	chunks                         []source.Chunk
	ref                            source.SourceRef
	value                          any
	candidate                      *CheckpointArtifact
}

func exactTypedValue[T any](operation string, value any) (T, error) {
	want := reflect.TypeFor[T]()
	if reflect.TypeOf(value) != want {
		var zero T
		return zero, fmt.Errorf("%s: expected exact Go type %s, got %T", operation, want, value)
	}
	typed, ok := value.(T)
	if !ok {
		var zero T
		return zero, fmt.Errorf("%s: expected exact Go type %s, got %T", operation, want, value)
	}
	return typed, nil
}

type typedExtractOperation func(context.Context, any, contracts.TypedExtractionRequest) (erasedTypedResult, error)
type typedMergeOperation func(context.Context, any, contracts.TypedMergeRequest[any]) (erasedTypedResult, error)
type typedNormalizeOperation func(context.Context, any, contracts.TypedNormalizeRequest[any]) (erasedTypedResult, error)
type typedValidateOperation func(context.Context, any, typedValidationTarget) (contracts.ValidationResult, error)
