package analytics

import (
	"context"
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

// TestRollupEngine_MultiAppNeutrality_JiraLikeSprintRollup verifies that the
// rollup engine processes a non-CRM domain (jira-like Epic/Story) without any
// CRM-specific code path. This is the acceptance test for multi-app neutrality
// deferred from PR-1a (#516) via DEC10.
//
// Fixture: Epic__c parent with TotalPoints__c (SUM of Story__c.StoryPoints__c
// via Story__c.EpicId__c), built inline below — no pack install path involved.
//
// Exercises: ProcessRollups (full engine dispatch) + implicit config validation
// via FindAffectedRollups + UpdateDerived call on the jira-like parent.
func TestRollupEngine_MultiAppNeutrality_JiraLikeSprintRollup(t *testing.T) {
	const (
		parentObj   = "Epic__c"
		parentID    = "epic-001"
		childObj    = "Story__c"
		rollupField = "TotalPoints__c"
		childField  = "StoryPoints__c"
		relField    = "EpicId__c"
		expectedSum = float64(8)
	)

	epicSchema := &models.ObjectMetadata{
		APIName: parentObj,
		Fields: []models.FieldMetadata{
			{
				APIName:    rollupField,
				Type:       constants.FieldTypeRollupSummary,
				Updateable: false,
				RollupConfig: &models.RollupConfig{
					CalcType:          "SUM",
					SummaryObject:     childObj,
					SummaryField:      childField,
					RelationshipField: relField,
				},
			},
		},
	}

	meta := newFakeMetadata(map[string]*models.ObjectMetadata{parentObj: epicSchema})
	repo := &stubRollupCalcRepo{calcValue: expectedSum}
	dw := &stubDerivedWriteCapture{}

	svc := NewRollupService(repo, meta, alwaysPessimisticRollupTxManager{}, noopLogger())
	svc.SetDerivedWriter(dw)

	// Child record representing a Story__c with 8 story points, linked to epic-001.
	childRecord := models.SObject{
		relField:   parentID,
		childField: expectedSum,
	}

	// Full engine dispatch: config validation → aggregation → UpdateDerived.
	if err := svc.ProcessRollups(context.Background(), childObj, childRecord); err != nil {
		t.Fatalf("ProcessRollups() error = %v; rollup engine must accept non-CRM jira-like domain", err)
	}

	// Multi-app neutrality assertion: engine dispatched to jira-like parent, not a CRM object.
	if len(dw.calls) != 1 {
		t.Fatalf("expected 1 UpdateDerived call, got %d; engine must route non-CRM domain without CRM-specific branches", len(dw.calls))
	}
	call := dw.calls[0]
	if call.objectName != parentObj {
		t.Errorf("UpdateDerived objectName = %q, want %q; engine must not hardcode CRM object names", call.objectName, parentObj)
	}
	if call.recordID != parentID {
		t.Errorf("UpdateDerived recordID = %q, want %q", call.recordID, parentID)
	}
	if val, ok := call.updates[rollupField]; !ok || val != expectedSum {
		t.Errorf("UpdateDerived updates[%q] = %v (ok=%v), want %v", rollupField, val, ok, expectedSum)
	}
}
