package analytics

import (
	"context"
	"fmt"
	"reflect"
	"sort"
	"strings"

	pkgErrors "github.com/nexuscrm/kernel/pkg/errors"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/nexuscrm/shared/pkg/queryspec"
)

// RegisterVirtualReportSource installs one immutable, product-owned source at
// process startup. The registry owns only execution dispatch; metadata remains
// authoritative for object/field shape and the permission service remains the
// only RLS/FLS decision path.
func (s *ReportService) RegisterVirtualReportSource(registration contract.VirtualReportSourceRegistration) error {
	if s == nil {
		return fmt.Errorf("analytics: virtual report source registrar is nil")
	}
	registration = cloneVirtualReportSourceRegistration(registration)
	registration.SourceRef = strings.TrimSpace(registration.SourceRef)
	registration.ParentObjectAPIName = strings.TrimSpace(registration.ParentObjectAPIName)
	if registration.SourceRef == "" {
		return fmt.Errorf("analytics: virtual report source ref is required")
	}
	if registration.ParentObjectAPIName == "" {
		return fmt.Errorf("analytics: virtual report source %q requires a parent object", registration.SourceRef)
	}
	if nilInterface(registration.Source) {
		return fmt.Errorf("analytics: virtual report source %q requires an executor", registration.SourceRef)
	}
	if !nilInterface(s.metadata) && s.metadata.GetSchema(context.Background(), registration.SourceRef) != nil {
		return fmt.Errorf("analytics: virtual report source %q conflicts with a physical object", registration.SourceRef)
	}
	if s.standardObjs != nil && s.standardObjs.Lookup(registration.SourceRef) != "" {
		return fmt.Errorf("analytics: virtual report source %q conflicts with a physical object", registration.SourceRef)
	}
	if LookupJoinTemplate(registration.SourceRef) != nil {
		return fmt.Errorf("analytics: virtual report source %q conflicts with a static report source", registration.SourceRef)
	}
	if (&syntheticParser{}).Parse(registration.SourceRef).shape != shapeUnknown {
		return fmt.Errorf("analytics: virtual report source %q conflicts with a synthetic custom report type", registration.SourceRef)
	}
	if len(registration.Columns) == 0 {
		return fmt.Errorf("analytics: virtual report source %q requires declared columns", registration.SourceRef)
	}

	joins := make(map[string]contract.VirtualReportJoin, len(registration.Joins))
	for i := range registration.Joins {
		join := registration.Joins[i]
		join.Name = strings.TrimSpace(join.Name)
		join.ObjectAPIName = strings.TrimSpace(join.ObjectAPIName)
		join.SourceRecordJoinRef = strings.TrimSpace(join.SourceRecordJoinRef)
		join.SourceFieldAPIName = strings.TrimSpace(join.SourceFieldAPIName)
		if join.Name == "" || join.ObjectAPIName == "" || join.SourceFieldAPIName == "" {
			return fmt.Errorf("analytics: virtual report source %q has an incomplete join", registration.SourceRef)
		}
		key := virtualReportNameKey(join.Name)
		if _, exists := joins[key]; exists {
			return fmt.Errorf("analytics: virtual report source %q declares duplicate join %q", registration.SourceRef, join.Name)
		}
		joins[key] = join
		registration.Joins[i] = join
	}
	for _, join := range registration.Joins {
		if join.SourceRecordJoinRef == "" {
			continue
		}
		sourceJoin, exists := joins[virtualReportNameKey(join.SourceRecordJoinRef)]
		if !exists || sourceJoin.Optional || sourceJoin.SourceRecordJoinRef != "" {
			return fmt.Errorf("analytics: virtual report source %q join %q source record must reference a required parent-bound join", registration.SourceRef, join.Name)
		}
	}
	if len(registration.Joins) > 0 && !registration.Capabilities.Joins {
		return fmt.Errorf("analytics: virtual report source %q declares joins without join capability", registration.SourceRef)
	}

	columnNames := make(map[string]struct{}, len(registration.Columns))
	for i := range registration.Columns {
		column := registration.Columns[i]
		column.Name = strings.TrimSpace(column.Name)
		column.JoinRef = strings.TrimSpace(column.JoinRef)
		if column.Name == "" {
			return fmt.Errorf("analytics: virtual report source %q has an unnamed column", registration.SourceRef)
		}
		key := virtualReportNameKey(column.Name)
		if _, exists := columnNames[key]; exists {
			return fmt.Errorf("analytics: virtual report source %q declares duplicate column %q", registration.SourceRef, column.Name)
		}
		columnNames[key] = struct{}{}
		if column.MetadataOnly && len(column.FieldReferences) > 0 {
			return fmt.Errorf("analytics: virtual report source %q metadata column %q cannot declare field dependencies", registration.SourceRef, column.Name)
		}
		if !column.MetadataOnly && len(column.FieldReferences) == 0 && !registration.RowFieldSecurityRequired {
			return fmt.Errorf("analytics: virtual report source %q column %q has no FLS dependency", registration.SourceRef, column.Name)
		}
		if column.JoinRef != "" {
			if _, exists := joins[virtualReportNameKey(column.JoinRef)]; !exists {
				return fmt.Errorf("analytics: virtual report source %q column %q references undeclared join %q", registration.SourceRef, column.Name, column.JoinRef)
			}
		}
		if column.Derived && !registration.Capabilities.Derived {
			return fmt.Errorf("analytics: virtual report source %q column %q is derived without derived capability", registration.SourceRef, column.Name)
		}
		if !nilInterface(column.Deriver) && !column.Derived {
			return fmt.Errorf("analytics: virtual report source %q column %q has a deriver without being derived", registration.SourceRef, column.Name)
		}
		if !nilInterface(column.Deriver) && len(column.FieldReferences) == 0 {
			return fmt.Errorf("analytics: virtual report source %q derived column %q has no FLS dependency", registration.SourceRef, column.Name)
		}
		fieldReferences := make(map[string]struct{}, len(column.FieldReferences))
		for j := range column.FieldReferences {
			ref := column.FieldReferences[j]
			ref.ObjectAPIName = strings.TrimSpace(ref.ObjectAPIName)
			ref.FieldAPIName = strings.TrimSpace(ref.FieldAPIName)
			if ref.ObjectAPIName == "" || ref.FieldAPIName == "" {
				return fmt.Errorf("analytics: virtual report source %q column %q has an incomplete field dependency", registration.SourceRef, column.Name)
			}
			key := virtualReportFieldReferenceKey(ref)
			if _, exists := fieldReferences[key]; exists {
				return fmt.Errorf("analytics: virtual report source %q column %q has duplicate field dependency %q.%q", registration.SourceRef, column.Name, ref.ObjectAPIName, ref.FieldAPIName)
			}
			fieldReferences[key] = struct{}{}
			column.FieldReferences[j] = ref
		}
		registration.Columns[i] = column
	}

	key := virtualReportNameKey(registration.SourceRef)
	s.virtualSourcesMu.Lock()
	defer s.virtualSourcesMu.Unlock()
	if s.virtualSources == nil {
		s.virtualSources = make(map[string]contract.VirtualReportSourceRegistration)
	}
	if _, exists := s.virtualSources[key]; exists {
		return fmt.Errorf("analytics: virtual report source %q is already registered", registration.SourceRef)
	}
	s.virtualSources[key] = cloneVirtualReportSourceRegistration(registration)
	return nil
}

func (s *ReportService) registeredVirtualReportSource(sourceRef string) (contract.VirtualReportSourceRegistration, bool) {
	if s == nil {
		return contract.VirtualReportSourceRegistration{}, false
	}
	s.virtualSourcesMu.RLock()
	defer s.virtualSourcesMu.RUnlock()
	if s.virtualSources == nil {
		return contract.VirtualReportSourceRegistration{}, false
	}
	registration, ok := s.virtualSources[virtualReportNameKey(sourceRef)]
	return cloneVirtualReportSourceRegistration(registration), ok
}

func (s *ReportService) registeredVirtualReportSourceForExecution(ctx context.Context, sourceRef string, user *models.UserSession) (contract.VirtualReportSourceRegistration, bool, error) {
	registration, ok := s.registeredVirtualReportSource(sourceRef)
	if !ok {
		return registration, false, nil
	}
	if resolver, supportsBindings := s.crtResolver.(virtualReportSourceBindingResolver); supportsBindings {
		_, bound, reportTypeExists, err := resolver.ResolveVirtualReportSourceBinding(ctx, sourceRef, user)
		if err != nil {
			return contract.VirtualReportSourceRegistration{}, false, err
		}
		if bound {
			if !ok {
				return contract.VirtualReportSourceRegistration{}, false, pkgErrors.NewInternalError(
					fmt.Sprintf("report type %q binds an unregistered virtual report source", sourceRef),
					nil,
				)
			}
			return registration, true, nil
		}
		if ok && reportTypeExists {
			return contract.VirtualReportSourceRegistration{}, false, pkgErrors.NewInternalError(
				fmt.Sprintf("virtual report source %q conflicts with a custom report type", sourceRef),
				nil,
			)
		}
		return registration, ok, nil
	}
	if s.crtResolver == nil {
		return registration, ok, nil
	}
	tmpl, _, err := s.crtResolver.Resolve(ctx, sourceRef, user)
	if err != nil {
		return contract.VirtualReportSourceRegistration{}, false, err
	}
	if tmpl != nil {
		return contract.VirtualReportSourceRegistration{}, false, pkgErrors.NewInternalError(
			fmt.Sprintf("virtual report source %q conflicts with a custom report type", sourceRef),
			nil,
		)
	}
	return registration, true, nil
}

func (s *ReportService) executeVirtualReport(
	ctx context.Context,
	def *models.ReportDefinition,
	registration contract.VirtualReportSourceRegistration,
	user *models.UserSession,
	runtimeFilters map[string]interface{},
	limit int,
	offset int,
) (*models.ReportResult, error) {
	if err := ctx.Err(); err != nil {
		return nil, err
	}
	request, requested, err := s.buildVirtualReportSourceRequest(def, registration, runtimeFilters, limit, offset)
	if err != nil {
		return nil, err
	}
	if err := s.authorizeVirtualReportRequest(ctx, registration, request.Columns, request.Joins, user); err != nil {
		return nil, err
	}

	sourceResult, err := registration.Source.Execute(ctx, cloneVirtualReportSourceRequest(request), user)
	if err != nil {
		return nil, err
	}
	if err := ctx.Err(); err != nil {
		return nil, err
	}
	if sourceResult == nil {
		return nil, pkgErrors.NewInternalError("virtual report source returned no result", nil)
	}
	if len(sourceResult.Rows) > request.Limit {
		return nil, pkgErrors.NewInternalError("virtual report source exceeded the requested page limit", nil)
	}
	if sourceResult.TotalCount < 0 || (len(sourceResult.Rows) > 0 && sourceResult.TotalCount > 0 && sourceResult.TotalCount < request.Offset+len(sourceResult.Rows)) {
		return nil, pkgErrors.NewInternalError("virtual report source returned an invalid total count", nil)
	}

	rows, err := s.authorizeVirtualReportRows(ctx, registration, request.Joins, requested, sourceResult.Rows, user)
	if err != nil {
		return nil, err
	}
	resultDef := request.Definition
	resultDef.DisplayMode = reportDisplayModeForExecution(resultDef.EffectiveDisplayMode(), resultDef.Grouping)
	resultDef.NormalizeBoundaryAliases()
	totalCount := sourceResult.TotalCount
	if totalCount == 0 {
		totalCount = len(rows)
	}
	return &models.ReportResult{
		ReportMetadata: resultDef,
		Rows:           rows,
		TotalCount:     totalCount,
	}, nil
}

func (s *ReportService) buildVirtualReportSourceRequest(
	def *models.ReportDefinition,
	registration contract.VirtualReportSourceRegistration,
	runtimeFilters map[string]interface{},
	limit int,
	offset int,
) (contract.VirtualReportSourceRequest, map[string]contract.VirtualReportColumn, error) {
	if def == nil {
		return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("reportMetadata", "report definition is required")
	}
	if offset < 0 {
		return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("offset", "report offset cannot be negative")
	}

	columnsByName := make(map[string]contract.VirtualReportColumn, len(registration.Columns))
	for _, column := range registration.Columns {
		columnsByName[virtualReportNameKey(column.Name)] = column
	}
	requested := make(map[string]contract.VirtualReportColumn)
	resolveColumn := func(raw string) (contract.VirtualReportColumn, error) {
		trimmed := strings.TrimSpace(raw)
		if column, ok := columnsByName[virtualReportNameKey(trimmed)]; ok {
			requested[virtualReportNameKey(column.Name)] = column
			return column, nil
		}
		normalized := strings.TrimSpace(s.normalizeReportColumn(trimmed))
		if column, ok := columnsByName[virtualReportNameKey(normalized)]; ok {
			requested[virtualReportNameKey(column.Name)] = column
			return column, nil
		}
		return contract.VirtualReportColumn{}, pkgErrors.NewValidationError("reportMetadata", fmt.Sprintf("virtual report column %q is not declared", trimmed))
	}

	normalized := *def
	normalized.Columns = append([]string(nil), def.Columns...)
	normalized.Filters = append([]models.ReportFilter(nil), def.Filters...)
	normalized.Grouping = append([]string(nil), def.Grouping...)
	normalized.Aggregates = append([]models.ReportAggregate(nil), def.Aggregates...)
	if def.DateFilter != nil {
		dateFilter := *def.DateFilter
		normalized.DateFilter = &dateFilter
	}

	for i, name := range normalized.Columns {
		column, err := resolveColumn(name)
		if err != nil {
			return contract.VirtualReportSourceRequest{}, nil, err
		}
		normalized.Columns[i] = column.Name
	}
	for i := range normalized.Filters {
		column, err := resolveColumn(normalized.Filters[i].Column)
		if err != nil {
			return contract.VirtualReportSourceRequest{}, nil, err
		}
		normalized.Filters[i].Column = column.Name
	}
	for i, name := range normalized.Grouping {
		column, err := resolveColumn(name)
		if err != nil {
			return contract.VirtualReportSourceRequest{}, nil, err
		}
		normalized.Grouping[i] = column.Name
	}
	for i := range normalized.Aggregates {
		if strings.TrimSpace(normalized.Aggregates[i].Field) == "" {
			continue
		}
		column, err := resolveColumn(normalized.Aggregates[i].Field)
		if err != nil {
			return contract.VirtualReportSourceRequest{}, nil, err
		}
		normalized.Aggregates[i].Field = column.Name
	}
	if normalized.DateFilter != nil && strings.TrimSpace(normalized.DateFilter.Column) != "" {
		column, err := resolveColumn(normalized.DateFilter.Column)
		if err != nil {
			return contract.VirtualReportSourceRequest{}, nil, err
		}
		normalized.DateFilter.Column = column.Name
	}

	normalizedRuntimeFilters := make(map[string]interface{}, len(runtimeFilters))
	for name, value := range runtimeFilters {
		column, err := resolveColumn(name)
		if err != nil {
			return contract.VirtualReportSourceRequest{}, nil, err
		}
		normalizedRuntimeFilters[column.Name] = value
	}
	if len(normalized.Columns) == 0 && len(normalized.Grouping) == 0 && len(normalized.Aggregates) == 0 {
		for _, column := range registration.Columns {
			requested[virtualReportNameKey(column.Name)] = column
		}
	}

	filtersRequested := len(normalized.Filters) > 0 || len(normalizedRuntimeFilters) > 0 || normalized.DateFilter != nil
	scope := strings.TrimSpace(normalized.Scope)
	filtersRequested = filtersRequested || (scope != "" && !strings.EqualFold(scope, "all"))
	if filtersRequested && !registration.Capabilities.Filters {
		return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("reportMetadata", "virtual report source does not support filters")
	}
	if (len(normalized.Grouping) > 0 || len(normalized.Aggregates) > 0) && !registration.Capabilities.Grouping {
		return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("reportMetadata", "virtual report source does not support grouping")
	}
	if !registration.Capabilities.Pagination {
		return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("reportMetadata", "virtual report source does not support pagination")
	}

	requestColumns := make([]contract.VirtualReportColumn, 0, len(requested))
	joinNames := make(map[string]struct{})
	joinsByName := make(map[string]contract.VirtualReportJoin, len(registration.Joins))
	for _, join := range registration.Joins {
		joinsByName[virtualReportNameKey(join.Name)] = join
	}
	for _, column := range registration.Columns {
		if _, ok := requested[virtualReportNameKey(column.Name)]; !ok {
			continue
		}
		requestColumns = append(requestColumns, column)
		if column.Derived && !registration.Capabilities.Derived {
			return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("reportMetadata", "virtual report source does not support derived columns")
		}
		if column.JoinRef != "" {
			joinNames[virtualReportNameKey(column.JoinRef)] = struct{}{}
		}
	}
	requestedJoinNames := sortedVirtualReportNames(joinNames)
	for _, joinName := range requestedJoinNames {
		join := joinsByName[joinName]
		if join.SourceRecordJoinRef != "" {
			joinNames[virtualReportNameKey(join.SourceRecordJoinRef)] = struct{}{}
		}
	}
	requestJoins := make([]contract.VirtualReportJoin, 0, len(joinNames))
	for _, join := range registration.Joins {
		if _, ok := joinNames[virtualReportNameKey(join.Name)]; ok {
			requestJoins = append(requestJoins, join)
		}
	}
	if len(requestJoins) > 0 && !registration.Capabilities.Joins {
		return contract.VirtualReportSourceRequest{}, nil, pkgErrors.NewValidationError("reportMetadata", "virtual report source does not support joins")
	}

	return contract.VirtualReportSourceRequest{
		Definition:     normalized,
		RuntimeFilters: normalizedRuntimeFilters,
		Columns:        requestColumns,
		Joins:          requestJoins,
		Limit:          limit,
		Offset:         offset,
	}, requested, nil
}

func (s *ReportService) authorizeVirtualReportRequest(
	ctx context.Context,
	registration contract.VirtualReportSourceRegistration,
	columns []contract.VirtualReportColumn,
	joins []contract.VirtualReportJoin,
	user *models.UserSession,
) error {
	if s.permissions == nil {
		return pkgErrors.NewInternalError("virtual report permission authority is not configured", nil)
	}
	if !s.permissions.CheckObjectPermissionWithUser(ctx, registration.ParentObjectAPIName, constants.PermRead, user) {
		return pkgErrors.NewPermissionError("read", registration.ParentObjectAPIName)
	}
	seen := make(map[string]struct{})
	for _, column := range columns {
		for _, ref := range column.FieldReferences {
			if err := s.authorizeVirtualReportField(ctx, ref, user, seen); err != nil {
				return err
			}
		}
	}
	for _, join := range joins {
		objectName := registration.ParentObjectAPIName
		if join.SourceRecordJoinRef != "" {
			for _, proofJoin := range joins {
				if virtualReportNameKey(proofJoin.Name) == virtualReportNameKey(join.SourceRecordJoinRef) {
					objectName = proofJoin.ObjectAPIName
					break
				}
			}
		}
		if err := s.authorizeVirtualReportField(ctx, contract.VirtualReportFieldReference{
			ObjectAPIName: objectName,
			FieldAPIName:  join.SourceFieldAPIName,
		}, user, seen); err != nil {
			return err
		}
	}
	return nil
}

type virtualReportHistoryAuthority interface {
	QueryHistory(context.Context, contract.HistoryQueryRequest, *models.UserSession) (*contract.HistoryQueryResult, error)
}

func (s *ReportService) authorizeVirtualReportRows(
	ctx context.Context,
	registration contract.VirtualReportSourceRegistration,
	joins []contract.VirtualReportJoin,
	requested map[string]contract.VirtualReportColumn,
	rows []contract.VirtualReportRow,
	user *models.UserSession,
) ([]models.Record, error) {
	if s.permissions == nil || s.queryService == nil {
		return nil, pkgErrors.NewInternalError("virtual report authorization dependencies are not configured", nil)
	}
	allowedObjectNames := map[string]struct{}{virtualReportNameKey(registration.ParentObjectAPIName): {}}
	requiredObjectNames := map[string]struct{}{virtualReportNameKey(registration.ParentObjectAPIName): {}}
	joinObjects := make(map[string]string, len(joins))
	joinsByName := make(map[string]contract.VirtualReportJoin, len(joins))
	for _, join := range joins {
		objectKey := virtualReportNameKey(join.ObjectAPIName)
		allowedObjectNames[objectKey] = struct{}{}
		if !join.Optional {
			requiredObjectNames[objectKey] = struct{}{}
		}
		joinKey := virtualReportNameKey(join.Name)
		joinObjects[joinKey] = join.ObjectAPIName
		joinsByName[joinKey] = join
	}

	type rowPlan struct {
		accessIDs       map[string]string
		historyRecordID string
	}
	plans := make([]rowPlan, len(rows))
	idsByObject := make(map[string]map[string]struct{})
	fieldsByObject := make(map[string]map[string]struct{})
	historyIDs := make(map[string]struct{})
	seenFields := make(map[string]struct{})
	for rowIndex, row := range rows {
		seenObjectNames := make(map[string]struct{})
		seenValues := make(map[string]struct{}, len(row.Values))
		plans[rowIndex].accessIDs = make(map[string]string, len(row.AccessRecords))
		for _, access := range row.AccessRecords {
			objectName := strings.TrimSpace(access.ObjectAPIName)
			key := virtualReportNameKey(objectName)
			if _, ok := allowedObjectNames[key]; !ok {
				return nil, pkgErrors.NewInternalError("virtual report row returned undeclared access evidence", nil)
			}
			if _, duplicate := seenObjectNames[key]; duplicate {
				return nil, pkgErrors.NewInternalError("virtual report row returned duplicate access evidence", nil)
			}
			recordID := strings.TrimSpace(access.RecordID)
			if recordID == "" {
				return nil, pkgErrors.NewInternalError("virtual report row returned incomplete access evidence", nil)
			}
			plans[rowIndex].accessIDs[key] = recordID
			if idsByObject[key] == nil {
				idsByObject[key] = make(map[string]struct{})
			}
			idsByObject[key][recordID] = struct{}{}
			if fieldsByObject[key] == nil {
				fieldsByObject[key] = map[string]struct{}{"Id": {}}
			}
			seenObjectNames[key] = struct{}{}
		}
		for required := range requiredObjectNames {
			if _, ok := seenObjectNames[required]; !ok {
				return nil, pkgErrors.NewInternalError("virtual report row omitted required record-access evidence", nil)
			}
		}
		for _, join := range joinsByName {
			sourceObjectName := registration.ParentObjectAPIName
			if join.SourceRecordJoinRef != "" {
				sourceObjectName = joinObjects[virtualReportNameKey(join.SourceRecordJoinRef)]
			}
			sourceObjectKey := virtualReportNameKey(sourceObjectName)
			if fieldsByObject[sourceObjectKey] == nil {
				fieldsByObject[sourceObjectKey] = map[string]struct{}{"Id": {}}
			}
			fieldsByObject[sourceObjectKey][join.SourceFieldAPIName] = struct{}{}
		}
		plans[rowIndex].historyRecordID = strings.TrimSpace(row.HistoryRecordID)
		if plans[rowIndex].historyRecordID != "" {
			historyIDs[plans[rowIndex].historyRecordID] = struct{}{}
		}
		for name, value := range row.Values {
			valueKey := virtualReportNameKey(name)
			column, ok := requested[valueKey]
			if !ok {
				return nil, pkgErrors.NewInternalError("virtual report source returned an undeclared or unrequested column", nil)
			}
			if _, duplicate := seenValues[valueKey]; duplicate {
				return nil, pkgErrors.NewInternalError("virtual report source returned duplicate normalized columns", nil)
			}
			seenValues[valueKey] = struct{}{}
			if len(value.HistoryInputs) > 0 {
				if value.History != nil || value.RecordObjectName() != "" || value.RecordFieldName != "" || value.RowFieldReference != nil || column.JoinRef != "" {
					return nil, pkgErrors.NewInternalError("virtual report derived value returned mixed projection evidence", nil)
				}
				if !column.Derived || nilInterface(column.Deriver) {
					return nil, pkgErrors.NewInternalError("virtual report history inputs require a registered derived column", nil)
				}
				if plans[rowIndex].historyRecordID == "" || len(column.FieldReferences) == 0 {
					return nil, pkgErrors.NewInternalError("virtual report derived history inputs require declared FLS dependencies", nil)
				}
				for _, input := range value.HistoryInputs {
					historyID := strings.TrimSpace(input.RecordID)
					if historyID == "" {
						return nil, pkgErrors.NewInternalError("virtual report derived history input is incomplete", nil)
					}
					historyIDs[historyID] = struct{}{}
				}
				continue
			}
			if value.History != nil {
				if value.RecordObjectName() != "" || value.RecordFieldName != "" || value.RowFieldReference != nil || column.JoinRef != "" {
					return nil, pkgErrors.NewInternalError("virtual report history value returned mixed projection evidence", nil)
				}
				historyID := strings.TrimSpace(value.History.RecordID)
				if plans[rowIndex].historyRecordID == "" || historyID == "" {
					return nil, pkgErrors.NewInternalError("virtual report history projection is incomplete", nil)
				}
				if historyID != plans[rowIndex].historyRecordID {
					if !column.Derived {
						return nil, pkgErrors.NewInternalError("virtual report history projection does not match its row", nil)
					}
					if len(column.FieldReferences) == 0 {
						return nil, pkgErrors.NewInternalError("virtual report off-anchor history projection requires a declared FLS dependency", nil)
					}
				}
				historyIDs[historyID] = struct{}{}
				continue
			}
			if column.JoinRef != "" {
				join := joinsByName[virtualReportNameKey(column.JoinRef)]
				if join.Optional {
					objectKey := virtualReportNameKey(join.ObjectAPIName)
					if _, hasAccess := plans[rowIndex].accessIDs[objectKey]; !hasAccess && virtualReportValueEmpty(value) {
						continue
					}
				}
			}
			if registration.RowFieldSecurityRequired && plans[rowIndex].historyRecordID == "" {
				if value.RowFieldReference == nil ||
					virtualReportNameKey(value.RowFieldReference.ObjectAPIName) != virtualReportNameKey(registration.ParentObjectAPIName) {
					return nil, pkgErrors.NewInternalError("virtual report value omitted required parent row-field authorization evidence", nil)
				}
				if err := s.authorizeVirtualReportField(ctx, *value.RowFieldReference, user, seenFields); err != nil {
					return nil, err
				}
			} else if value.RowFieldReference != nil {
				return nil, pkgErrors.NewInternalError("virtual report value returned undeclared row-field authorization evidence", nil)
			}
			expectedObjectName := registration.ParentObjectAPIName
			if column.JoinRef != "" {
				joinKey := virtualReportNameKey(column.JoinRef)
				expectedObjectName = joinObjects[joinKey]
			}
			if virtualReportNameKey(value.RecordObjectName()) != virtualReportNameKey(expectedObjectName) {
				return nil, pkgErrors.NewInternalError("virtual report value is not bound to its declared access record", nil)
			}
			recordFieldName := strings.TrimSpace(value.RecordFieldName)
			if recordFieldName == "" {
				return nil, pkgErrors.NewInternalError("virtual report value omitted its access-record field", nil)
			}
			if column.MetadataOnly {
				if !strings.EqualFold(recordFieldName, "Id") {
					return nil, pkgErrors.NewInternalError("virtual report metadata value is not an authoritative record id", nil)
				}
			} else if !virtualReportColumnAllowsRecordField(column, expectedObjectName, recordFieldName) {
				if !registration.RowFieldSecurityRequired || value.RowFieldReference == nil ||
					virtualReportNameKey(recordFieldName) != virtualReportNameKey(value.RowFieldReference.FieldAPIName) {
					return nil, pkgErrors.NewInternalError("virtual report value field is not a declared FLS dependency", nil)
				}
			}
			objectKey := virtualReportNameKey(expectedObjectName)
			if _, ok := plans[rowIndex].accessIDs[objectKey]; !ok {
				return nil, pkgErrors.NewInternalError("virtual report value has no authoritative source record", nil)
			}
			fieldsByObject[objectKey][recordFieldName] = struct{}{}
		}
		for requestedKey := range requested {
			if _, ok := seenValues[requestedKey]; !ok {
				return nil, pkgErrors.NewInternalError("virtual report source omitted a requested column", nil)
			}
		}
	}

	recordsByObject := make(map[string]map[string]models.Record, len(idsByObject))
	for objectKey, idSet := range idsByObject {
		objectName := registration.ParentObjectAPIName
		for _, join := range joins {
			if virtualReportNameKey(join.ObjectAPIName) == objectKey {
				objectName = join.ObjectAPIName
				break
			}
		}
		ids := sortedVirtualReportNames(idSet)
		fields := sortedVirtualReportNames(fieldsByObject[objectKey])
		result, err := s.queryService.QueryWithSpec(ctx, queryspec.QuerySpec{
			ObjectAPIName: objectName,
			SelectFields:  fields,
			Filter:        queryspec.FieldPredicate("Id", "IN", ids),
			Limit:         len(ids),
		}, user)
		if err != nil {
			return nil, err
		}
		recordsByObject[objectKey] = make(map[string]models.Record, len(ids))
		if result != nil {
			for _, record := range result.Records {
				recordID := strings.TrimSpace(fmt.Sprint(record["Id"]))
				if recordID == "" {
					return nil, pkgErrors.NewInternalError("virtual report authority returned a record without id", nil)
				}
				if _, duplicate := recordsByObject[objectKey][recordID]; duplicate {
					return nil, pkgErrors.NewInternalError("virtual report authority returned duplicate records", nil)
				}
				if _, requested := idSet[recordID]; !requested {
					return nil, pkgErrors.NewInternalError("virtual report authority returned an unrequested record", nil)
				}
				recordsByObject[objectKey][recordID] = record
			}
		}
	}

	historyRecords := make(map[string]contract.HistoryRecord, len(historyIDs))
	if len(historyIDs) > 0 {
		authority, ok := s.queryService.(virtualReportHistoryAuthority)
		if !ok {
			return nil, pkgErrors.NewInternalError("virtual report history authority is not configured", nil)
		}
		ids := sortedVirtualReportNames(historyIDs)
		result, err := authority.QueryHistory(ctx, contract.HistoryQueryRequest{
			ParentObjectAPIName: registration.ParentObjectAPIName,
			SelectFields:        []string{"Id", "ParentId", "Field", "OldValue", "NewValue", "DataType", "CreatedDate", "CreatedById"},
			Filter:              queryspec.FieldPredicate("Id", "IN", ids),
			Limit:               len(ids),
			PageSize:            len(ids),
		}, user)
		if err != nil {
			return nil, err
		}
		if result != nil {
			for _, record := range result.Rows {
				if record.ID == "" {
					return nil, pkgErrors.NewInternalError("virtual report history authority returned a row without id", nil)
				}
				if _, requested := historyIDs[record.ID]; !requested {
					return nil, pkgErrors.NewInternalError("virtual report history authority returned an unrequested row", nil)
				}
				if _, duplicate := historyRecords[record.ID]; duplicate {
					return nil, pkgErrors.NewInternalError("virtual report history authority returned duplicate rows", nil)
				}
				historyRecords[record.ID] = record
			}
		}
	}

	out := make([]models.Record, 0, len(rows))
	for rowIndex, row := range rows {
		for _, join := range joinsByName {
			sourceObjectName := registration.ParentObjectAPIName
			if join.SourceRecordJoinRef != "" {
				sourceObjectName = joinObjects[virtualReportNameKey(join.SourceRecordJoinRef)]
			}
			sourceObjectKey := virtualReportNameKey(sourceObjectName)
			sourceRecordID := plans[rowIndex].accessIDs[sourceObjectKey]
			sourceRecord, ok := recordsByObject[sourceObjectKey][sourceRecordID]
			if !ok {
				return nil, pkgErrors.NewPermissionError("read record on", sourceObjectName)
			}
			relatedIDValue, ok := sourceRecord[join.SourceFieldAPIName]
			if !ok {
				return nil, pkgErrors.NewInternalError("virtual report join relationship field is unavailable", nil)
			}
			relatedID := virtualReportRecordID(relatedIDValue)
			joinedID := plans[rowIndex].accessIDs[virtualReportNameKey(join.ObjectAPIName)]
			if relatedID == "" {
				if !join.Optional || joinedID != "" {
					return nil, pkgErrors.NewInternalError("virtual report join relationship evidence is contradicted", nil)
				}
				continue
			}
			if joinedID == "" || joinedID != relatedID {
				return nil, pkgErrors.NewInternalError("virtual report join relationship evidence is contradicted", nil)
			}
		}
		parentID := plans[rowIndex].accessIDs[virtualReportNameKey(registration.ParentObjectAPIName)]
		if historyID := plans[rowIndex].historyRecordID; historyID != "" {
			history, ok := historyRecords[historyID]
			if !ok || history.ParentID != parentID {
				return nil, pkgErrors.NewPermissionError("read history on", registration.ParentObjectAPIName)
			}
		}
		values := make(models.Record, len(row.Values))
		for name, value := range row.Values {
			column := requested[virtualReportNameKey(name)]
			if len(value.HistoryInputs) > 0 {
				inputs := make([]interface{}, 0, len(value.HistoryInputs))
				for _, input := range value.HistoryInputs {
					history, ok := historyRecords[strings.TrimSpace(input.RecordID)]
					if !ok || history.ParentID != parentID {
						return nil, pkgErrors.NewPermissionError("read history on", registration.ParentObjectAPIName)
					}
					if !virtualReportHistoryColumnAllows(column, registration.ParentObjectAPIName, history, input.Field) {
						return nil, pkgErrors.NewInternalError("virtual report history field is not a declared FLS dependency", nil)
					}
					projected, err := projectVirtualReportHistoryValue(history, input)
					if err != nil {
						return nil, err
					}
					inputs = append(inputs, projected)
				}
				derived, err := column.Deriver.DeriveVirtualReportValue(inputs)
				if err != nil {
					return nil, pkgErrors.NewInternalError("virtual report derived value calculation failed", err)
				}
				values[column.Name] = derived
				continue
			}
			if value.History != nil {
				history, ok := historyRecords[strings.TrimSpace(value.History.RecordID)]
				if !ok || history.ParentID != parentID {
					return nil, pkgErrors.NewPermissionError("read history on", registration.ParentObjectAPIName)
				}
				if !virtualReportHistoryColumnAllows(column, registration.ParentObjectAPIName, history, value.History.Field) {
					return nil, pkgErrors.NewInternalError("virtual report history field is not a declared FLS dependency", nil)
				}
				projected, err := projectVirtualReportHistoryValue(history, *value.History)
				if err != nil {
					return nil, err
				}
				values[column.Name] = projected
				continue
			}
			expectedObjectName := registration.ParentObjectAPIName
			if column.JoinRef != "" {
				joinKey := virtualReportNameKey(column.JoinRef)
				join := joinsByName[joinKey]
				expectedObjectName = joinObjects[joinKey]
				if join.Optional {
					objectKey := virtualReportNameKey(expectedObjectName)
					if _, hasAccess := plans[rowIndex].accessIDs[objectKey]; !hasAccess {
						values[column.Name] = nil
						continue
					}
				}
			}
			objectKey := virtualReportNameKey(expectedObjectName)
			recordID := plans[rowIndex].accessIDs[objectKey]
			record, ok := recordsByObject[objectKey][recordID]
			if !ok {
				return nil, pkgErrors.NewPermissionError("read record on", expectedObjectName)
			}
			projectedValue, ok := record[strings.TrimSpace(value.RecordFieldName)]
			if !ok {
				return nil, pkgErrors.NewInternalError("virtual report authoritative field is unavailable", nil)
			}
			values[column.Name] = projectedValue
		}
		out = append(out, values)
	}
	return out, nil
}

func virtualReportValueEmpty(value contract.VirtualReportValue) bool {
	return value.RecordObjectName() == "" && value.RecordFieldName == "" && value.RowFieldReference == nil && value.History == nil && len(value.HistoryInputs) == 0
}

func virtualReportRecordID(value interface{}) string {
	if value == nil {
		return ""
	}
	return strings.TrimSpace(fmt.Sprint(value))
}

func virtualReportColumnAllowsRecordField(column contract.VirtualReportColumn, objectName, fieldName string) bool {
	for _, ref := range column.FieldReferences {
		if virtualReportNameKey(ref.ObjectAPIName) == virtualReportNameKey(objectName) &&
			virtualReportNameKey(ref.FieldAPIName) == virtualReportNameKey(fieldName) {
			return true
		}
	}
	return false
}

func sortedVirtualReportNames(values map[string]struct{}) []string {
	out := make([]string, 0, len(values))
	for value := range values {
		out = append(out, value)
	}
	sort.Strings(out)
	return out
}

func virtualReportHistoryColumnAllows(column contract.VirtualReportColumn, parentObject string, history contract.HistoryRecord, projectionField contract.VirtualReportHistoryField) bool {
	if column.MetadataOnly {
		return projectionField == contract.VirtualReportHistoryID
	}
	if len(column.FieldReferences) == 0 {
		return true
	}
	for _, ref := range column.FieldReferences {
		if virtualReportNameKey(ref.ObjectAPIName) == virtualReportNameKey(parentObject) &&
			virtualReportNameKey(ref.FieldAPIName) == virtualReportNameKey(history.Field) {
			return true
		}
	}
	return false
}

func projectVirtualReportHistoryValue(
	history contract.HistoryRecord,
	projection contract.VirtualReportHistoryProjection,
) (interface{}, error) {
	switch projection.Field {
	case contract.VirtualReportHistoryID:
		return history.ID, nil
	case contract.VirtualReportHistoryParentID:
		return history.ParentID, nil
	case contract.VirtualReportHistoryFieldName:
		return history.Field, nil
	case contract.VirtualReportHistoryOldValue:
		if history.OldValue == nil {
			return nil, nil
		}
		return *history.OldValue, nil
	case contract.VirtualReportHistoryNewValue:
		if history.NewValue == nil {
			return nil, nil
		}
		return *history.NewValue, nil
	case contract.VirtualReportHistoryDataType:
		return history.DataType, nil
	case contract.VirtualReportHistoryCreatedDate:
		return history.CreatedDate, nil
	case contract.VirtualReportHistoryCreatedByID:
		return history.CreatedByID, nil
	default:
		return nil, pkgErrors.NewInternalError("virtual report history projection field is unsupported", nil)
	}
}

func virtualReportFieldReferenceKey(ref contract.VirtualReportFieldReference) string {
	return virtualReportNameKey(ref.ObjectAPIName) + "." + virtualReportNameKey(ref.FieldAPIName)
}

func (s *ReportService) authorizeVirtualReportField(
	ctx context.Context,
	ref contract.VirtualReportFieldReference,
	user *models.UserSession,
	seen map[string]struct{},
) error {
	objectName := strings.TrimSpace(ref.ObjectAPIName)
	fieldName := strings.TrimSpace(ref.FieldAPIName)
	if objectName == "" || fieldName == "" {
		return pkgErrors.NewInternalError("virtual report field-security evidence is incomplete", nil)
	}
	key := virtualReportNameKey(objectName) + "." + virtualReportNameKey(fieldName)
	if _, ok := seen[key]; ok {
		return nil
	}
	seen[key] = struct{}{}
	if !s.permissions.CheckObjectPermissionWithUser(ctx, objectName, constants.PermRead, user) {
		return pkgErrors.NewPermissionError("read", objectName)
	}
	allowed, err := s.permissions.CheckFieldVisibilityWithUser(ctx, objectName, fieldName, user)
	if err != nil {
		return pkgErrors.NewInternalError("virtual report field permission authority is unavailable", err)
	}
	if !allowed {
		return pkgErrors.NewPermissionError("read field "+fieldName+" on", objectName)
	}
	return nil
}

func cloneVirtualReportSourceRegistration(in contract.VirtualReportSourceRegistration) contract.VirtualReportSourceRegistration {
	out := in
	out.Columns = append([]contract.VirtualReportColumn(nil), in.Columns...)
	for i := range out.Columns {
		out.Columns[i].FieldReferences = append([]contract.VirtualReportFieldReference(nil), in.Columns[i].FieldReferences...)
	}
	out.Joins = cloneVirtualReportJoins(in.Joins)
	return out
}

func cloneVirtualReportSourceRequest(in contract.VirtualReportSourceRequest) contract.VirtualReportSourceRequest {
	out := in
	out.Definition = in.Definition
	out.Definition.Columns = append([]string(nil), in.Definition.Columns...)
	out.Definition.Filters = append([]models.ReportFilter(nil), in.Definition.Filters...)
	out.Definition.Grouping = append([]string(nil), in.Definition.Grouping...)
	out.Definition.Aggregates = append([]models.ReportAggregate(nil), in.Definition.Aggregates...)
	if in.Definition.DateFilter != nil {
		dateFilter := *in.Definition.DateFilter
		out.Definition.DateFilter = &dateFilter
	}
	out.RuntimeFilters = make(map[string]interface{}, len(in.RuntimeFilters))
	for name, value := range in.RuntimeFilters {
		out.RuntimeFilters[name] = value
	}
	out.Columns = append([]contract.VirtualReportColumn(nil), in.Columns...)
	for i := range out.Columns {
		out.Columns[i].FieldReferences = append([]contract.VirtualReportFieldReference(nil), in.Columns[i].FieldReferences...)
	}
	out.Joins = cloneVirtualReportJoins(in.Joins)
	return out
}

func cloneVirtualReportJoins(in []contract.VirtualReportJoin) []contract.VirtualReportJoin {
	return append([]contract.VirtualReportJoin(nil), in...)
}

func virtualReportNameKey(value string) string {
	return strings.ToLower(strings.TrimSpace(value))
}

func nilInterface(value interface{}) bool {
	if value == nil {
		return true
	}
	v := reflect.ValueOf(value)
	switch v.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	default:
		return false
	}
}
