package ru.dbotthepony.mc.otm.datagen.advancements

import net.minecraft.advancements.Advancement
import net.minecraft.advancements.FrameType
import net.minecraft.advancements.RequirementsStrategy
import net.minecraft.advancements.critereon.ItemPredicate
import net.minecraft.network.chat.contents.TranslatableContents
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.common.data.ExistingFileHelper
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.key
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.datagen.lang.MatteryLanguageProvider
import ru.dbotthepony.mc.otm.datagen.modLocation
import ru.dbotthepony.mc.otm.registry.MItemTags
import ru.dbotthepony.mc.otm.registry.MItems
import ru.dbotthepony.mc.otm.triggers.TakeItemOutOfReplicatorTrigger
import java.util.function.Consumer

private data class CraftEntry(
	val item: Item,
	val englishName: String,
	val englishSuffix: String? = null,

	val russianName: String? = null,
	val russianSuffix: String? = null,
) {
	fun make(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, parent: Advancement, translation: MatteryLanguageProvider.MultiBuilder): Advancement {
		val path = item.registryName!!.path

		val translated = translation.add("$path.desc", "Craft a %s%s") {
			russian("Создайте %s%s")
		}

		val translatedSuffix = translation.add("$path.suffix", if (englishSuffix != null) ". $englishSuffix" else "") {
			russian(if (russianSuffix != null) ". $russianSuffix" else "")
		}

		return AdvancementBuilder()
			.parent(parent)
			.display(
				itemStack = ItemStack(item),
				title = translation.add(path, englishName) {
					if (russianName != null) {
						russian(russianName)
					}
				},
				description = TranslatableComponent(translated.contents.key, item.description, translatedSuffix),
			)
			.addCriterion("has_machine", criterion(item))
			.save(serializer, modLocation("machines/$path"), existingFileHelper)
	}
}

fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, lang: MatteryLanguageProvider, root: Advancement) {
	val translation = lang.MultiBuilder("otm.advancements.machine")

	val chem = AdvancementBuilder()
		.parent(root)
		.display(
			itemStack = ItemStack(MItems.CHEMICAL_GENERATOR),
			title = translation.add("chemical_generator", "Burning the Organics") {
				russian("Сжигание органики")
			},
			description = translation.add("chemical_generator.desc", "Craft a Chemical Generator, better to put it outside") {
				russian("Создайте химический генератор. Лучше установить его снаружи")
			},
		)
		.addCriterion("has_machine", criterion(MItems.CHEMICAL_GENERATOR))
		.save(serializer, modLocation("machines/chemical_generator"), existingFileHelper)

	val press = AdvancementBuilder()
		.parent(chem)
		.display(
			itemStack = ItemStack(MItems.PLATE_PRESS),
			title = translation.add("plate_press", "Bending the Material") {
				russian("Раскатка металла")
			},
			description = translation.add("plate_press.desc", "Craft a Plate Press, avoid having limbs inside at all times") {
				russian("Создайте пресс пластин, не суйте свои или чужие конечности внутрь")
			},
		)
		.addCriterion("has_machine", criterion(MItems.PLATE_PRESS))
		.save(serializer, modLocation("machines/plate_press"), existingFileHelper)

	CraftEntry(MItems.TWIN_PLATE_PRESS, "Twice the Thud",
		russianName = "Двойной стук").make(serializer, existingFileHelper, press, translation)

	val scanner = CraftEntry(MItems.MATTER_SCANNER, "Scanning Things that Matter",
		russianName = "Сканируем вещи которые материальны")
	val decomposer = CraftEntry(MItems.MATTER_DECOMPOSER, "Decaying the Atoms", "Keep your limbs outside of the working chamber at all times",
		russianName = "Разлагаем атомы", russianSuffix = "Во всех ситуациях держите свои конечности вне рабочей камеры")
	val panel = CraftEntry(MItems.MATTER_PANEL, "Indexing the Library",
		russianName = "Индексируем библиотеку")
	val replicator = CraftEntry(MItems.MATTER_REPLICATOR, "Cook with (Im)Perfection", "Now let's bake some perfect bread",
		russianName = "Повар с (не) идеальностями", russianSuffix = "А теперь давайте выпечем немного идеального хлеба")
	val bottler = CraftEntry(MItems.MATTER_BOTTLER, "Transfusing Pure Matter", "For those who loved to play with water in their childhood",
		russianName = "Переливаем чистую материю", russianSuffix = "Для тех, кто любил играться в воде в детстве")
	val recycler = CraftEntry(MItems.MATTER_RECYCLER, "Refine and Redefine", "This is what waste recycling should look like",
		russianName = "Переработка и перегонка", russianSuffix = "Вот он, пик переработки отходов")
	val capacitor = CraftEntry(MItems.MATTER_CAPACITOR_BANK, "Modular Matter Tank",
		russianName = "Модульный бак материи")

	val counter = CraftEntry(MItems.ENERGY_COUNTER, "Visualize Power Burn",
		russianName = "Визуализация сжигания энергии")
	val battery = CraftEntry(MItems.BATTERY_BANK, "Batteries Not Included", "By all means avoid the urge to hammer incompatible batteries into the power bus.",
		russianName = "Батарейки в комплект не входят", russianSuffix = "Пожалуйста, воздержитесь от вбивания кувалдой несовместимых батарей в энергетическую шину.")

	val pattern = CraftEntry(MItems.PATTERN_STORAGE, "Digital Knowledge Library",
		russianName = "Цифровая библиотека знаний")

	val reconstructor = CraftEntry(MItems.MATTER_RECONSTRUCTOR, "Flipping Hourglass",
		russianName = "Переворачиваем песочные часы")

	decomposer.make(serializer, existingFileHelper, press, translation).also {
		pattern.make(serializer, existingFileHelper, it, translation).also {
			scanner.make(serializer, existingFileHelper, it, translation)
			panel.make(serializer, existingFileHelper, it, translation)

			replicator.make(serializer, existingFileHelper, it, translation).also {
				AdvancementBuilder()
					.parent(it)
					.display(
						itemStack = ItemStack(Items.BREAD),
						title = translation.add("replicate_something", "Local Bakery") {
							russian("Местная выпечка")
						},
						description = translation.add("replicate_something.desc", "Replicate something using Matter Replicator. If you replicated some food, be first to taste it among your company") {
							russian("Среплицируйте что либо используя репликатор материи. Если это еда, то не стесняйтесь быть первым, кто попробует её на вкус среди вашей компании")
						},
						frameType = FrameType.GOAL
					)
					.addCriterion("replicate_something", TakeItemOutOfReplicatorTrigger.Instance(ItemPredicate.Builder.item().of(MItems.MATTER_DUST).build(), true))
					.save(serializer, modLocation("machines/replicate_something"), existingFileHelper)

				AdvancementBuilder()
					.parent(it)
					.display(
						hidden = true,
						itemStack = ItemStack(MItems.MATTER_DUST),
						title = translation.add("replicate_failure", "Unhealthy Flavor") {
							russian("Вредная посыпка")
						},
						description = translation.add("replicate_failure.desc", "Experience replication failure and have your thing turn into matter dust") {
							russian("Наблюдайте неудачный результат репликации, где ваш заказ рассыпался в материальную труху")
						},
					)
					.addCriterion("replicate_failure", TakeItemOutOfReplicatorTrigger.Instance(ItemPredicate.Builder.item().of(MItems.MATTER_DUST).build()))
					.save(serializer, modLocation("machines/replicate_failure"), existingFileHelper)
			}

			reconstructor.make(serializer, existingFileHelper, it, translation)
		}

		bottler.make(serializer, existingFileHelper, it, translation)
		recycler.make(serializer, existingFileHelper, it, translation)
		capacitor.make(serializer, existingFileHelper, it, translation)
	}

	counter.make(serializer, existingFileHelper, press, translation).also {
		battery.make(serializer, existingFileHelper, it, translation)
	}

	val station = CraftEntry(MItems.ANDROID_STATION, "Android Home Page",
		russianName = "Домашняя страница андроидов",
		russianSuffix = "Только пользоваться этим устройством могут вёдра с болтами",
		englishSuffix = "Except only buckets of bolts can use this thing")

	val charger = CraftEntry(MItems.ANDROID_CHARGER, "Android Home Router",
		russianName = "Домашняя страница андроидов")

	station.make(serializer, existingFileHelper, press, translation).also {
		charger.make(serializer, existingFileHelper, it, translation)
	}

	CraftEntry(MItems.COBBLESTONE_GENERATOR, "Cobblestone: Infinity + 1",
		russianName = "Булыжник: бесконечность + 1",
		russianSuffix = "Смотрите, чтоб он не просыпался во все сундуки",
		englishSuffix = "Watch for not to spill it over all your chests").make(serializer, existingFileHelper, press, translation)
}
