package automation

import (
	"context"

	connector "github.com/pingcap-inc/nexuscrm-contract/pkg/connector"
	runtimeports "github.com/pingcap-inc/nexuscrm-contract/pkg/runtimeports"
)

// bootstrapFieldMappingApplier is the production FieldMappingApplier. It
// resolves rows from _System_ObjectFieldMapping via the injected
// ConnectorFieldMappingReader port (the canonical registry reader) and copies
// fields from source to target using registry-declared rules. Keeping the
// lookup behind the FieldMappingApplier interface keeps the registry-read
// dependency out of FlowExecutor proper; depending on the port (rather than the
// bootstrap package directly) inverts the dependency so the concrete reader is
// wired at the composition root.
type bootstrapFieldMappingApplier struct {
	reader runtimeports.ConnectorFieldMappingReader
}

// NewBootstrapFieldMappingApplier returns a FieldMappingApplier that reads the
// registry through the injected ConnectorFieldMappingReader port. Intended for
// service-manager wiring.
func NewBootstrapFieldMappingApplier(reader runtimeports.ConnectorFieldMappingReader) FieldMappingApplier {
	return &bootstrapFieldMappingApplier{reader: reader}
}

func (a *bootstrapFieldMappingApplier) ApplyMappings(ctx context.Context, sourceObject, targetObject, actionType string, source, target map[string]interface{}) error {
	mappings, err := a.reader.GetFieldMappings(sourceObject, targetObject, actionType)
	if err != nil {
		return err
	}
	connector.ApplyFieldMappings(mappings, source, target)
	return nil
}

// ConnectorMappingResolver is the production seam for direction-aware connector
// field-mapping reads. Implemented by bootstrapConnectorFieldMappingResolver;
// the interface keeps the registry-read dependency behind a narrow surface in
// FlowExecutor.
type ConnectorMappingResolver interface {
	ResolveConnectorMappings(ctx context.Context, q connector.ResolveQuery) ([]connector.ConnectorFieldMappingInput, error)
	ResolvePackConnectorMappings(ctx context.Context, q connector.ResolveQuery) ([]connector.ConnectorFieldMappingInput, error)
}

// bootstrapConnectorFieldMappingResolver is the production ConnectorMappingResolver.
// It delegates to the injected ConnectorFieldMappingReader port.
type bootstrapConnectorFieldMappingResolver struct {
	reader runtimeports.ConnectorFieldMappingReader
}

// NewBootstrapConnectorFieldMappingResolver returns a ConnectorMappingResolver
// backed by the injected ConnectorFieldMappingReader port. Intended for
// service-manager wiring.
func NewBootstrapConnectorFieldMappingResolver(reader runtimeports.ConnectorFieldMappingReader) ConnectorMappingResolver {
	return &bootstrapConnectorFieldMappingResolver{reader: reader}
}

func (r *bootstrapConnectorFieldMappingResolver) ResolveConnectorMappings(ctx context.Context, q connector.ResolveQuery) ([]connector.ConnectorFieldMappingInput, error) {
	return r.reader.ResolveFieldMapping(ctx, q)
}

func (r *bootstrapConnectorFieldMappingResolver) ResolvePackConnectorMappings(ctx context.Context, q connector.ResolveQuery) ([]connector.ConnectorFieldMappingInput, error) {
	return r.reader.ResolvePackConnectorFieldMapping(ctx, q)
}
