package ru.dbotthepony.mc.otm.config

import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.registry.MNames

object MachinesConfig : AbstractConfig("machines") {
	val PLATE_PRESS = workerValues(
		MNames.PLATE_PRESS,
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(200),
		energyConsumption = Decimal(15),
		maxExperience = 200.0,
	)

	val MATTER_ENTANGLER = workerValues(
		MNames.MATTER_ENTANGLER,
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(400),
		energyConsumption = Decimal(120),
		matterCapacity = Decimal(60),
		maxExperience = 400.0,
	)

	val MATTER_DECOMPOSER = workerValues(
		MNames.MATTER_DECOMPOSER,
		energyStorage = Decimal(100_000),
		energyThroughput = Decimal(400),
		energyConsumption = Decimal(240),
		matterCapacity = Decimal(400),
	)

	val MATTER_SCANNER = workerValues(
		MNames.MATTER_SCANNER,
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(200),
		energyConsumption = Decimal(80),
	)

	val MATTER_REPLICATOR = workerValues(
		MNames.MATTER_REPLICATOR,
		energyStorage = Decimal(200_000),
		energyThroughput = Decimal(4_000),
		energyConsumption = Decimal(400),
		matterCapacity = Decimal(200)
	)

	private val MATTER_RECYCLER = workerValues(
		MNames.MATTER_RECYCLER,
		energyStorage = Decimal(80_000),
		energyThroughput = Decimal(400),
		energyConsumption = Decimal(100),
		matterCapacity = Decimal(400),
		workTimeMultiplier = null
	) {
		MatterRecycler
	}

	private val MATTER_BOTTLER = workerValues(
		MNames.MATTER_BOTTLER,
		energyStorage = Decimal(40_000),
		energyConsumption = Decimal(10),
		energyThroughput = Decimal(200),
		matterCapacity = Decimal(400),
		workTimeMultiplier = null
	) {
		MatterBottler
	}

	private val CHEMICAL_GENERATOR = workerValues(
		MNames.CHEMICAL_GENERATOR,
		energyStorage = Decimal(32_000),
		energyThroughput = Decimal(160),
		energyConsumption = Decimal(40),
		workTimeMultiplier = null
	) {
		ChemicalGenerator
	}

	object ChemicalGenerator {
		val VALUES by ::CHEMICAL_GENERATOR
		val RATIO: Int by builder.comment("This amount of burn ticks result in 1 generation tick").defineInRange("RATIO", 2, 0)
	}

	object MatterBottler {
		val VALUES by ::MATTER_BOTTLER
		val RATE by builder.comment("Matter transferred per tick").defineDecimal("RATE", Decimal("2.0"), Decimal.ONE_TENTH)
	}

	object MatterRecycler {
		val VALUES by ::MATTER_RECYCLER
		val MATTER_PER_TICK by builder.defineDecimal("MATTER_PER_TICK", Decimal("0.5"))
	}

	private val ANDROID_STATION = workerValues(
		MNames.ANDROID_STATION,
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(8_000),
		energyConsumption = null,
		workTimeMultiplier = null,
	) {
		AndroidStation
	}

	object AndroidStation {
		val VALUES by ::ANDROID_STATION
		val ENERGY_PER_OPERATION by builder.comment("Swapping parts").defineDecimal("ENERGY_PER_OPERATION", Decimal(2_000), Decimal.ZERO)
		val ENERGY_PER_RESEARCH by builder.comment("Researching android stuff").defineDecimal("ENERGY_PER_RESEARCH", Decimal(16_000), Decimal.ZERO)
	}

	private val MATTER_RECONSTRUCTOR = workerValues(
		MNames.MATTER_RECONSTRUCTOR,
		energyStorage = Decimal(100_000),
		energyThroughput = Decimal(1000),
		energyConsumption = Decimal(400),
		matterCapacity = Decimal(200),
		workTimeMultiplier = null,
	) {
		MatterReconstructor
	}

	object MatterReconstructor {
		val VALUES by ::MATTER_RECONSTRUCTOR

		val ALLOW_TO_SKIP_ANVIL: Boolean by builder
			.comment("Allow to repair tools without having their anvil-repair items researched")
			.comment("Ignored if onlyAnvil is true")
			.define("ALLOW_TO_SKIP_ANVIL", false)

		val ONLY_ANVIL: Boolean by builder
			.comment("Force repairing only by matter value of anvil materials")
			.comment("Doesn't make logical sense but might be good for balancing")
			.define("ONLY_ANVIL", false)

		val FAILURE_CHANCE: Double by builder
			.comment("Constant additional chance (over pattern research factor) that replication will fail at any given tick")
			.comment("In event of failure repair tick is wasted, as well as resources")
			.defineInRange("FAILURE_CHANCE", 0.01, 0.0, 0.99)

		val DIVISOR: Double by builder
			.comment("Magnitute of **slowdown** of repairer.")
			.comment("If this value is 1, repairer will repair item from 0% to 100% in COMPLEXITY (of tool) ticks")
			.comment("(or twice the complexity of anvil repair ingredients if tool itself has no matter value)")
			.comment("---")
			.comment("If value is smaller than 1, repairer will repair items faster")
			.comment("If value is bigger than 1, repairer will repair items slower")
			.defineInRange("DIVISOR", 3.0, 0.1, Double.MAX_VALUE)
	}

	val STORAGE_POWER_SUPPLIER = conciseValues(MNames.STORAGE_POWER_SUPPLIER, Decimal(80_000), Decimal(2_000))
	val STORAGE_INTERFACES = conciseValues("STORAGE_INTERFACES", Decimal(10_000), Decimal(10_000))
	val ITEM_MONITOR = conciseValues(MNames.ITEM_MONITOR, Decimal(10_000), Decimal(10_000))
	val DRIVE_VIEWER = conciseValues(MNames.DRIVE_VIEWER, Decimal(10_000), Decimal(10_000))
	val DRIVE_RACK = conciseValues(MNames.DRIVE_RACK, Decimal(10_000), Decimal(10_000))

	object AndroidCharger {
		val RADIUS_WIDTH: Double by builder
			.comment("Effective charger range on horizontal plane")
			.defineInRange("RADIUS_WIDTH", 16.0, 1.0, Double.MAX_VALUE)

		val RADIUS_HEIGHT: Double by builder
			.comment("Effective charger range on vertical plane")
			.defineInRange("RADIUS_HEIGHT", 4.0, 1.0, Double.MAX_VALUE)
	}

	val ANDROID_CHARGER = conciseValues(MNames.ANDROID_CHARGER, Decimal(1_000_000), Decimal(8192)) { AndroidCharger }

	val POWERED_FURNACE = workerValues(
		"POWERED_FURNACE",
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(200),
		energyConsumption = Decimal(20),
		workTimeMultiplier = 0.75,
		maxExperience = 200.0
	)

	val POWERED_BLAST_FURNACE = workerValues(
		"POWERED_BLAST_FURNACE",
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(200),
		energyConsumption = Decimal(20),
		workTimeMultiplier = 0.75,
		maxExperience = 200.0
	)

	val POWERED_SMOKER = workerValues(
		"POWERED_SMOKER",
		energyStorage = Decimal(40_000),
		energyThroughput = Decimal(200),
		energyConsumption = Decimal(10),
		workTimeMultiplier = 0.75,
		maxExperience = 200.0
	)

	object Upgrades {
		init {
			builder.push("UPGRADES")
		}

		val MIN_SPEED: Double by builder
			.comment("Minimal combined upgrade speed percentage (upgrades can't decrease machine speed below this)")
			.defineInRange("MIN_SPEED", -0.8, -1.0, Double.MAX_VALUE)

		val MAX_SPEED: Double by builder
			.comment("Maximal combined upgrade speed percentage")
			.defineInRange("MAX_SPEED", Double.MAX_VALUE, 0.0, Double.MAX_VALUE)

		val MIN_ENERGY by builder
			.comment("Minimal combined energy consumption percentage (upgrades can't decrease machine energy consumption below this)")
			.defineDecimal("MIN_ENERGY", Decimal(-0.8), Decimal(-1.0))

		val MAX_ENERGY by builder
			.comment("Maximal combined energy consumption percentage")
			.defineDecimal("MAX_ENERGY", Decimal.POSITIVE_INFINITY, Decimal.ZERO)

		init {
			builder.pop()
		}
	}

	init {
		Upgrades
	}
}
