package enemyevents

import (
	"sort"

	"gitea.maximumdirect.net/eric/notarius/internal/core/source"
	"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
	"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
)

type orderedEnemyEvent struct {
	value       dnd.EnemyEvent
	earliest    int
	hasEvidence bool
}

func canonicalEnemyEventList(response extractionResponse, order shared.SourceRefOrder, sourceID string) dnd.EnemyEventList {
	if response.Events == nil {
		return dnd.EnemyEventList{}
	}
	ordered := make([]orderedEnemyEvent, len(response.Events))
	for index, event := range response.Events {
		refs := order.Canonicalize(order.OrderEndpoints(sourceRefs(event.SourceRefs, sourceID)))
		earliest, hasEvidence := order.EarliestValid(refs)
		ordered[index] = orderedEnemyEvent{
			value: dnd.EnemyEvent{
				Name:       event.Name,
				Kind:       dnd.EnemyEventKind(event.Kind),
				SourceRefs: refs,
			},
			earliest:    earliest,
			hasEvidence: hasEvidence,
		}
	}
	sort.SliceStable(ordered, func(left, right int) bool {
		if ordered[left].hasEvidence != ordered[right].hasEvidence {
			return ordered[left].hasEvidence
		}
		if !ordered[left].hasEvidence {
			return false
		}
		return ordered[left].earliest < ordered[right].earliest
	})
	events := make([]dnd.EnemyEvent, len(ordered))
	for index := range ordered {
		events[index] = ordered[index].value
	}
	return dnd.EnemyEventList{Events: events}
}

func sourceRefs(refs []enemySourceRefResponse, sourceID string) []source.SourceRef {
	if refs == nil {
		return nil
	}
	values := make([]source.SourceRef, len(refs))
	for index, ref := range refs {
		values[index] = source.SourceRef{SourceID: sourceID, StartUnitID: ref.StartUnitID, EndUnitID: ref.EndUnitID}
	}
	return values
}
