package audit

import (
	"encoding/json"
	"strings"
	"testing"
	"time"
)

func TestDelayedFieldExpansionPreservesReservedHistorySequence(t *testing.T) {
	sequence := int64(42)
	eligible := false
	event := AuditEvent{
		ObjectApiName: "Account",
		RecordId:      "record-1",
		Action:        ActionUpdate,
		ChangedById:   "user-1",
		Entrypoint:    EntrypointRestAPI,
		Outcome:       OutcomeSuccess,
		FieldDiffs: []FieldDiff{{
			FieldName:            "Name",
			OldValue:             "old",
			NewValue:             "new",
			FieldHistoryEligible: &eligible,
			HistorySequence:      &sequence,
		}},
	}
	rows := ExpandFieldRows(event, OutboxRow{ID: 7, EnqueuedAt: time.Now()}, time.Now)
	if len(rows) != 1 || rows[0].HistorySequence == nil || *rows[0].HistorySequence != sequence {
		t.Fatalf("expanded rows = %#v, want preserved sequence %d", rows, sequence)
	}
	if rows[0].FieldHistoryEligible == nil || *rows[0].FieldHistoryEligible {
		t.Fatalf("expanded rows = %#v, want preserved false eligibility", rows)
	}
}

func TestFieldHistoryEligibilityJSONRollingCompatibility(t *testing.T) {
	sequence := int64(42)
	eligible := false
	newEvent := AuditEvent{
		ObjectApiName: "Account", RecordId: "record-1", Action: ActionUpdate,
		ChangedById: "user-1", Entrypoint: EntrypointRestAPI, Outcome: OutcomeSuccess,
		FieldDiffs: []FieldDiff{{
			FieldName: "Name", OldValue: "old", NewValue: "new",
			HistorySequence: &sequence, FieldHistoryEligible: &eligible,
		}},
	}
	payload, err := json.Marshal(newEvent)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(string(payload), `"FieldHistoryEligible":false`) {
		t.Fatalf("new producer payload = %s, want explicit false eligibility", payload)
	}
	var legacy struct {
		FieldDiffs []struct {
			FieldName       string
			HistorySequence *int64
		}
	}
	if err := json.Unmarshal(payload, &legacy); err != nil {
		t.Fatal(err)
	}
	if len(legacy.FieldDiffs) != 1 || legacy.FieldDiffs[0].HistorySequence == nil || *legacy.FieldDiffs[0].HistorySequence != sequence {
		t.Fatalf("legacy worker view = %#v, want sequence retained while new boolean is ignored", legacy)
	}

	oldPayload := []byte(`{"ObjectApiName":"Account","RecordId":"record-1","Action":"UPDATE","ChangedById":"user-1","Entrypoint":"REST_API","Outcome":"SUCCESS","FieldDiffs":[{"FieldName":"Name","OldValue":"old","NewValue":"new","HistorySequence":42}]}`)
	var decoded AuditEvent
	if err := json.Unmarshal(oldPayload, &decoded); err != nil {
		t.Fatal(err)
	}
	if len(decoded.FieldDiffs) != 1 || decoded.FieldDiffs[0].FieldHistoryEligible != nil || decoded.FieldDiffs[0].HistorySequence == nil {
		t.Fatalf("new worker decoded old payload = %#v, want nil eligibility plus legacy sequence", decoded)
	}
}
