class_name TickProcess
extends Node

# Dependency injection - can be overridden for simulation
# Using Variant to accept both Node (singletons) and RefCounted (IsolatedGameState)
var unlocks_provider = null
var inventory_provider = null

func _ready():
	# Default to singletons if not explicitly set
	_ensure_providers_initialized()

func _ensure_providers_initialized():
	"""Ensure providers are set (called before every tick if needed)"""
	if unlocks_provider == null:
		unlocks_provider = Unlocks
	if inventory_provider == null:
		inventory_provider = Inventory

func set_providers(unlocks, inventory):
	"""Set custom providers for simulation (bypasses singletons)"""
	unlocks_provider = unlocks
	inventory_provider = inventory

func tick():
	# Log.pr("Tick Process Ticking...")
	_ensure_providers_initialized()  # Safety check before each tick
	do_autowood()
	do_whittling()
	do_selling()
	do_reputation_income()

func do_autowood():
	# If the autowood unlock is unlocked then automatically gain wood based on the modifier
	var autowood_unlock = unlocks_provider.get_unlock_by_id(Global.autowood_unlock_id)
	if autowood_unlock and autowood_unlock.is_unlocked:
		# Log.pr("Autowood modifier", str(unlocks_provider.get_modifier_value("autowood_modifier")))
		var wood_to_gather = max(unlocks_provider.get_wood_per_click() * unlocks_provider.get_modifier_value("autowood_modifier"), 1)
		inventory_provider.add_wood(wood_to_gather)
		# Log.pr("Auto-gathered", str(wood_to_gather), "wood via autowood unlock.")

func do_whittling():
	# If there's more than 1 whole wood available, then whittle based on the efficiency modifier
	if inventory_provider.get_wood() >= 1:
		whittle_max_wood_possible()

	## If multicraft is unlocked, whittle additional wood based on multicraft unlock
	var multicraft_unlock = unlocks_provider.get_unlock_by_id(Global.multicraft_unlock_id)
	if multicraft_unlock and multicraft_unlock.is_unlocked:
		var additional_whittles = multicraft_unlock.current_rank # Each rank allows one additional whittling action
		for i in range(additional_whittles):
			if inventory_provider.get_wood() >= 1:
				whittle_max_wood_possible()
			else:
				break

func do_selling():
	# If the wholesale unlock is purchased, sell blocks of 100 whittled wood if possible
	var wholesale_unlock = unlocks_provider.get_unlock_by_id(Global.wholesale_unlock_id)
	if wholesale_unlock and wholesale_unlock.is_unlocked:
		while inventory_provider.get_stock() >= Global.wholesale_bundle_size:
			inventory_provider.spend_stock(Global.wholesale_bundle_size)
			var currency_earned = Global.wholesale_bundle_size * unlocks_provider.get_sale_price_per_item() * Global.wholesale_discount_multiplier
			inventory_provider.add_currency(currency_earned)
			# Log.pr("Sold 100 whittled wood for", str(currency_earned), "currency via wholesale unlock.")


	# If there's whittled wood available to sell, sell it for currency
	if inventory_provider.get_stock() > 0:
		var whittle_wood_to_sell = inventory_provider.get_stock()
		# Sell whatever people are willing to buy
		var purchase_rate = Global.base_purchase_rate * unlocks_provider.get_modifier_value("purchase_rate_modifier")
		var max_stock_to_sell = floor(purchase_rate)

		# Sell up to the max stock to sell this tick, but no more than available stock
		# We should always sell at least one, up to the max
		var actual_stock_to_sell = min(whittle_wood_to_sell, max(1, max_stock_to_sell))

		inventory_provider.spend_stock(actual_stock_to_sell)
		var currency_earned = actual_stock_to_sell * unlocks_provider.get_sale_price_per_item()
		inventory_provider.add_currency(currency_earned)

	
func whittle_max_wood_possible():
	# Get the items that can be produced per tick
	var items_produced_per_tick = unlocks_provider.get_items_produced_per_tick()
	# Log.pr("Items produced per tick:", str(items_produced_per_tick))
	var wood_needed = ceil(items_produced_per_tick)

	# Whittle as much wood as possible this tick, up to the max allowed by efficiency
	var wood_to_whittle = min(inventory_provider.get_wood(), wood_needed)
	var actual_items_produced = wood_to_whittle

	inventory_provider.spend_wood(wood_to_whittle)
	inventory_provider.add_stock(actual_items_produced)
	# Log.pr("Whittled", str(wood_to_whittle), "wood into", str(actual_items_produced), "whittle wood.")

func do_reputation_income():
	# Add passive income from reputation unlock
	var reputation_income = unlocks_provider.get_modifier_value("reputation_income")
	if reputation_income > 0:
		inventory_provider.add_currency(reputation_income)
