package register

import (
	"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
	"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
	"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
	"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/chunk/scenes"
	combatcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
	enemyeventcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/enemyevents"
	itemoccurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/itemoccurrences"
	itemregistrycodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/itemregistry"
	locationoccurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/locationoccurrences"
	locationcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/locationregistry"
	occurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcoccurrences"
	npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcregistry"
	scenedescriptioncodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
	spellcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/spells"
	combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
	enemyeventextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/enemyevents"
	itemoccurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/itemoccurrences"
	itemregistryextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/itemregistry"
	locationoccurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/locationoccurrences"
	locationextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/locationregistry"
	occurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcoccurrences"
	npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcregistry"
	scenedescriptionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
	spellextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
	combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
	enemyeventnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/enemyevents"
	itemoccurrencenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/itemoccurrences"
	itemregistrynormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/itemregistry"
	locationoccurrencenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/locationoccurrences"
	locationnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/locationregistry"
	occurrencenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcoccurrences"
	npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcregistry"
	scenedescriptionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/scenedescriptions"
	spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
	combatsemantics "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/combat_semantics"
	"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/merge/appendorder"
	"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/normalize/noop"
)

func registerModules(registries pipeline.Registries) error {
	codec := spellcodec.New()
	return runRegistrations([]registration{
		{name: "spells codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, codec) }},
		{name: "npc registry codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, npccodec.New()) }},
		{name: "combat turns codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, combatcodec.New()) }},
		{name: "enemy events codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, enemyeventcodec.New()) }},
		{name: "item occurrences codec", register: func() error {
			return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, itemoccurrencecodec.New())
		}},
		{name: "item registry codec", register: func() error {
			return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, itemregistrycodec.New())
		}},
		{name: "npc occurrences codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, occurrencecodec.New()) }},
		{name: "scene descriptions codec", register: func() error {
			return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, scenedescriptioncodec.New())
		}},
		{name: "location registry codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, locationcodec.New()) }},
		{name: "location occurrences codec", register: func() error {
			return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, locationoccurrencecodec.New())
		}},
		{name: "scenes chunker", register: func() error { return scenes.Register(registries.Chunkers) }},
		{name: "spells extractor", register: func() error { return spellextract.Register(registries.Extractors) }},
		{name: "npc registry extractor", register: func() error { return npcextract.Register(registries.Extractors) }},
		{name: "combat turns extractor", register: func() error { return combatextract.Register(registries.Extractors) }},
		{name: "enemy events extractor", register: func() error { return enemyeventextract.Register(registries.Extractors) }},
		{name: "item occurrences extractor", register: func() error { return itemoccurrenceextract.Register(registries.Extractors) }},
		{name: "item registry extractor", register: func() error { return itemregistryextract.Register(registries.Extractors) }},
		{name: "npc occurrences extractor", register: func() error { return occurrenceextract.Register(registries.Extractors) }},
		{name: "scene descriptions extractor", register: func() error { return scenedescriptionextract.Register(registries.Extractors) }},
		{name: "location registry extractor", register: func() error { return locationextract.Register(registries.Extractors) }},
		{name: "location occurrences extractor", register: func() error { return locationoccurrenceextract.Register(registries.Extractors) }},
		{name: "spell-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.SpellListKind, appendSpellLists)
		}},
		{name: "npc registry appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.NPCRegistryKind, appendNPCRegistries)
		}},
		{name: "combat-turn-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.CombatTurnListKind, appendCombatTurnLists)
		}},
		{name: "enemy-event-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.EnemyEventListKind, appendEnemyEventLists)
		}},
		{name: "item-occurrence-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.ItemOccurrenceListKind, appendItemOccurrenceLists)
		}},
		{name: "item-registry appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.ItemRegistryKind, appendItemRegistries)
		}},
		{name: "npc-occurrence-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.NPCOccurrenceListKind, appendNPCOccurrenceLists)
		}},
		{name: "scene-description-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.SceneDescriptionListKind, appendSceneDescriptionLists)
		}},
		{name: "location-registry appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.LocationRegistryKind, appendLocationRegistries)
		}},
		{name: "location-occurrence-list appendorder merger", register: func() error {
			return appendorder.RegisterTyped(registries.Mergers, dnd.LocationOccurrenceListKind, appendLocationOccurrenceLists)
		}},
		{name: "spells normalizer", register: func() error { return spellnormalize.Register(registries.Normalizers) }},
		{name: "npc registry normalizer", register: func() error { return npcnormalize.Register(registries.Normalizers) }},
		{name: "combat turns normalizer", register: func() error { return combatnormalize.Register(registries.Normalizers) }},
		{name: "enemy events normalizer", register: func() error { return enemyeventnormalize.Register(registries.Normalizers) }},
		{name: "item occurrences normalizer", register: func() error { return itemoccurrencenormalize.Register(registries.Normalizers) }},
		{name: "item registry normalizer", register: func() error { return itemregistrynormalize.Register(registries.Normalizers) }},
		{name: "npc occurrences normalizer", register: func() error { return occurrencenormalize.Register(registries.Normalizers) }},
		{name: "scene descriptions normalizer", register: func() error { return scenedescriptionnormalize.Register(registries.Normalizers) }},
		{name: "location registry normalizer", register: func() error { return locationnormalize.Register(registries.Normalizers) }},
		{name: "location occurrences normalizer", register: func() error { return locationoccurrencenormalize.Register(registries.Normalizers) }},
		{name: "spell-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.SpellList](registries.Normalizers, dnd.SpellListKind)
		}},
		{name: "npc registry noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.NPCRegistry](registries.Normalizers, dnd.NPCRegistryKind)
		}},
		{name: "combat-turn-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.CombatTurnList](registries.Normalizers, dnd.CombatTurnListKind)
		}},
		{name: "enemy-event-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.EnemyEventList](registries.Normalizers, dnd.EnemyEventListKind)
		}},
		{name: "item-occurrence-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.ItemOccurrenceList](registries.Normalizers, dnd.ItemOccurrenceListKind)
		}},
		{name: "item-registry noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.ItemRegistry](registries.Normalizers, dnd.ItemRegistryKind)
		}},
		{name: "npc-occurrence-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.NPCOccurrenceList](registries.Normalizers, dnd.NPCOccurrenceListKind)
		}},
		{name: "scene-description-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.SceneDescriptionList](registries.Normalizers, dnd.SceneDescriptionListKind)
		}},
		{name: "location-registry noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.LocationRegistry](registries.Normalizers, dnd.LocationRegistryKind)
		}},
		{name: "location-occurrence-list noop normalizer", register: func() error {
			return noop.RegisterTyped[dnd.LocationOccurrenceList](registries.Normalizers, dnd.LocationOccurrenceListKind)
		}},
	})
}

func registerPromptAssets(assets *llm.AssetRegistry) error {
	return runRegistrations([]registration{
		{name: "scenes prompt assets", register: func() error { return scenes.RegisterPromptAssets(assets) }},
		{name: "spells prompt assets", register: func() error { return spellextract.RegisterPromptAssets(assets) }},
		{name: "npc registry prompt assets", register: func() error { return npcextract.RegisterPromptAssets(assets) }},
		{name: "npc normalization prompt assets", register: func() error { return npcnormalize.RegisterPromptAssets(assets) }},
		{name: "combat turns prompt assets", register: func() error { return combatextract.RegisterPromptAssets(assets) }},
		{name: "enemy events prompt assets", register: func() error { return enemyeventextract.RegisterPromptAssets(assets) }},
		{name: "item occurrences prompt assets", register: func() error { return itemoccurrenceextract.RegisterPromptAssets(assets) }},
		{name: "item registry prompt assets", register: func() error { return itemregistryextract.RegisterPromptAssets(assets) }},
		{name: "item registry normalization prompt assets", register: func() error { return itemregistrynormalize.RegisterPromptAssets(assets) }},
		{name: "npc occurrences prompt assets", register: func() error { return occurrenceextract.RegisterPromptAssets(assets) }},
		{name: "scene descriptions prompt assets", register: func() error { return scenedescriptionextract.RegisterPromptAssets(assets) }},
		{name: "scene combat-semantics validator prompt assets", register: func() error { return combatsemantics.RegisterPromptAssets(assets) }},
		{name: "location registry prompt assets", register: func() error { return locationextract.RegisterPromptAssets(assets) }},
		{name: "location normalization prompt assets", register: func() error { return locationnormalize.RegisterPromptAssets(assets) }},
		{name: "location occurrences prompt assets", register: func() error { return locationoccurrenceextract.RegisterPromptAssets(assets) }},
	})
}
